If you want to avoid copying, then I suppose the Container must create the stored instances itself.
If you want to invoke the default constructor, then it should be no problem. Just invoke the default constructor of Container.
It is probably more problematic if you want to invoke a non-default constructor of the contained type. C++0x will have better solutions for that.
As an excercise, the container can accept a T, or an object containing the arguments for the constructor of T. This still relies on RVO (return value optimization).
template <class T1>
class construct_with_1
{
T1 _1;
public:
construct_with_1(const T1& t1): _1(t1) {}
template <class U>
U construct() const { return U(_1); }
};
template <class T1, class T2>
class construct_with_2
{
T1 _1;
T2 _2;
public:
construct_with_2(const T1& t1, const T2& t2): _1(t1), _2(t2) {}
template <class U>
U construct() const { return U(_1, _2); }
};
//etc for other arities
template <class T1>
construct_with_1<T1> construct_with(const T1& t1)
{
return construct_with_1<T1>(t1);
}
template <class T1, class T2>
construct_with_2<T1, T2> construct_with(const T1& t1, const T2& t2)
{
return construct_with_2<T1, T2>(t1, t2);
}
//etc
template <class T>
T construct(const T& source) { return source; }
template <class T, class T1>
T construct(const construct_with_1<T1>& args)
{
return args.template construct<T>();
}
template <class T, class T1, class T2>
T construct(const construct_with_2<T1, T2>& args)
{
return args.template construct<T>();
}
template <class T>
class Container
{
public:
T first, second;
template <class T1, class T2>
Container(const T1& a = T1(), const T2& b = T2()) :
first(construct<T>(a)), second(construct<T>(b)) {}
};
#include <iostream>
class Test
{
int n;
double d;
public:
Test(int a, double b = 0.0): n(a), d(b) { std::cout << "Test(" << a << ", " << b << ")\n"; }
Test(const Test& x): n(x.n), d(x.d) { std::cout << "Test(const Test&)\n"; }
void foo() const { std::cout << "Test.foo(" << n << ", " << d << ")\n"; }
};
int main()
{
Test test(4, 3.14);
Container<Test> a(construct_with(1), test); //first constructed internally, second copied
a.first.foo();
a.second.foo();
}