I have code that looks like this:
class T {};
class container {
const T &first, T &second;
container(const T&first, const T & second);
};
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 construct_with_1
{
T1 _1;
public:
construct_with_1(const T1& t1): _1(t1) {}
template
U construct() const { return U(_1); }
};
template
class construct_with_2
{
T1 _1;
T2 _2;
public:
construct_with_2(const T1& t1, const T2& t2): _1(t1), _2(t2) {}
template
U construct() const { return U(_1, _2); }
};
//etc for other arities
template
construct_with_1 construct_with(const T1& t1)
{
return construct_with_1(t1);
}
template
construct_with_2 construct_with(const T1& t1, const T2& t2)
{
return construct_with_2(t1, t2);
}
//etc
template
T construct(const T& source) { return source; }
template
T construct(const construct_with_1& args)
{
return args.template construct();
}
template
T construct(const construct_with_2& args)
{
return args.template construct();
}
template
class Container
{
public:
T first, second;
template
Container(const T1& a = T1(), const T2& b = T2()) :
first(construct(a)), second(construct(b)) {}
};
#include
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 a(construct_with(1), test); //first constructed internally, second copied
a.first.foo();
a.second.foo();
}