Search code examples
c++variadic-templates

Why do variadic templates fail to find an appropriate constructor?


If you look at main you'll see I can call write with 4, t2 (or t) but not both in the same call, why? Is there anything I can do outside of breaking them up into seperate calls?

template<class T>
struct Test
{
    T data;

    constexpr Test()=default;
    Test(Test&)=delete;

    void Write() { }

    template<typename...Args>
    void Write(unsigned int v, Args...args) {
        Write(args...);
    }

    template<typename...Args>
    void Write(int v, Args...args) {
        Write(args...);
    }

    template<typename...Args>
    void Write(char v, Args...args) {
        Write(args...);
    }

    template<typename...Args>
    void Write(const Test<char>&v, Args...args) { Write(args...); }
};

int main()
{
    Test<char> t;
    const Test<char>&t2=t;
    t.Write(4); //ok
    t.Write(t2);//ok
    t.Write(0, t2); //not ok
}

Solution

  • As you've deleted the copy-constructor the last line will not work. One way to fix it is passing the variadic args as reference like:

    #include <iostream>
    
    template<class T>
    struct Test
    {
        T data;
    
        constexpr Test()=default;
        Test(Test&)=delete;
    
        void Write() { }
    
        template<typename...Args>
        void Write(unsigned int v, Args&...args) {
            Write(args...);
        }
    
        template<typename...Args>
        void Write(int v, Args&...args) {
            Write(args...);
        }
    
        template<typename...Args>
        void Write(char v, Args&...args) {
            Write(args...);
        }
    
        template<typename...Args>
        void Write(const Test<char>&v, Args&...args) { Write(args...); }
    };
    
    int main()
    {
        Test<char> t;
        const Test<char>&t2=t;
        t.Write(4); //ok
        t.Write(t2);//ok
        t.Write(0, t2); //ok
    }