Writing variadic template constructor

前端 未结 4 738
无人共我
无人共我 2021-02-02 10:38

Recently I asked this question but now I would like to expand it. I wrote the following class:

template 
class X{
public:
    vector v;
          


        
4条回答
  •  被撕碎了的回忆
    2021-02-02 11:22

    First, your code doesn't compile for me.

    main.cpp:7:15: error: declaration of ‘class T’
         template 
                   ^
    main.cpp:3:11: error:  shadows template parm ‘class T’
     template 
               ^
    

    I changed the outer one to U.

    template 
    class X{
    public:
        vector v;
        template 
        X(T n) {
            v.push_back(n);
        }
        template 
        X(T n, T2... rest) {
            v.push_back(n);
            X(rest...);
        }
    };
    

    You're correct that this causes the issue you gave in the question details...

    X obj(1, 2, 3);  // obj.v containts only 1
    

    This is because the statement X(rest...) at the end of your constructor doesn't recursively call the constructor to continue initializing the same object; it creates a new X object and then throws it away. Once a constructor's body begins to execute, it's no longer possible to invoke another constructor on the same object. Delegation must occur in the ctor-initializer. So for example, you could do this:

    template 
    X(T n, T2... rest): X(rest...) {
        v.insert(v.begin(), n);
    }
    

    That sucks though, because inserting at the beginning of a vector isn't efficient.

    Better to take a std::initializer_list argument. This is what std::vector itself does.

    X(std::initializer_list il): v(il) {}
    // ...
    X obj {1, 2, 3};
    

提交回复
热议问题