C++ constant reference lifetime (container adaptor)

前端 未结 5 1460
花落未央
花落未央 2020-11-28 12:54

I have code that looks like this:

class T {};

class container {
 const T &first, T &second;
 container(const T&first, const T & second);
};
         


        
5条回答
  •  孤街浪徒
    2020-11-28 13:30

    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();
    }
    

提交回复
热议问题