I'm trying to write a code attempts a deduction of two parameter packs in template and was wondering why the following code doesn't work
t.h (doesn't work)
#pragma once
#include <tuple>
namespace example
{
template<typename ... T>
struct Foo;
template<typename ... T1, typename ... T2>
struct Foo<std::tuple<T1...>, std::tuple<T2...>>
{
std::tuple<T1...> t1;
std::tuple<T2...> t2;
Foo(const std::tuple<T1...>& x, const std::tuple<T2...>& y) : t1(x), t2(y)
{
}
};
}
t.cpp
#include "t.h"
int main()
{
using namespace example;
using T1 = std::tuple<int>;
example::Foo f(T1{}, T1{});
return 0;
}
When I try to compile the code above, the compiler gives me the following error:
error: no viable constructor or deduction guide for deduction of template arguments of 'Foo'
example::Foo f(T1{}, T1{});
After playing around a bit, I found out I can make the code work by adding a user defined deduction guide as follows
t.h (works)
namespace example
{
template<typename ... T>
struct Foo;
template<typename ... T1, typename ... T2>
struct Foo<std::tuple<T1...>, std::tuple<T2...>>
{
std::tuple<T1...> t1;
std::tuple<T2...> t2;
Foo(const std::tuple<T1...>& x, const std::tuple<T2...>& y) : t1(x), t2(y)
{
}
};
// After adding this deduction guide, things work
template<typename T1, typename T2>
Foo(const T1& t1, const T2& out) -> Foo<T1, T2>;
}
The Question
My question is twofold. First, why does the compiler need a deduction guide in this case in the first place, and second, how does it work? I'm still learning the newer language features of C++ 20/23 and I'm using clang++ compiler.
Thanks for reading!