Home > database >  Failed parameter pack deduction of template arguments in a template specialization
Failed parameter pack deduction of template arguments in a template specialization

Time:08-28

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!

CodePudding user response:

Implicit deduction guides are generated based on the constructors of the primary template, not any of its specializations. Your primary template has no constructors, so no deduction guides exist.

For class template argument deduction, the function arguments to the constructor are compared against the deduction guides to figure out what the template arguments are. These arguments are applied to the template, which is when specialization happens.

  • Related