c++c++23

Why does deduction guide detect template arguments as an empty set?


This code fails because the compiler thinks template arguments for Test is an empty set.

#include <tuple>

template <typename... T>
class Test
{
public:
    template <typename Arg, typename... Args>
    Test(Arg&& arg1, Args&&... args) : tuple_{std::forward<Arg>(arg1), std::forward<Args>(args)...} 
    {}

private:
    std::tuple<T...> tuple_;
};


template <typename... Ts>
Test(Ts...) -> Test<Ts...>;

int main()
{
    Test t{1, 2};
}

why is that? Live example

Changing deduction guide to "fully match" the constructor works on the other hand


Solution

  • From cppinsight you might see the auto-generated deduction guide as well (comment mine):

    template<typename... Ts, typename Arg, typename... Args>
    Test(Arg&& arg1, Args&&... args) -> Test<Ts...>; // Empty Ts as Ts not deducible
    

    And it is a better match than your explicit deduction guide for Test t{1, 2};

    template <typename... Ts> Test(Ts...) -> Test<Ts...>;
    

    Several solutions:

    template <typename T, typename... Ts> Test(T, Ts...) -> Test<T, Ts...>;
    

    There is a tie-breaker explicit versus implicit.