Template argument deduction with alias template partially specializing a class template

93 Views Asked by At

With C++20, is there a way to use class template argument deduction with an alias template that partially specializes a template class?

The following code shows what I'd like to achieve but fails to compile with g++12:

template <typename T, typename U> struct foo;

template <typename T> struct foo<T, int> {
  const T t;

  foo(T t) : t(t) {}
};

template <typename T> using foo_int = foo<T, int>;

int main() {
  auto bar = foo_int(1.0); // FAILS
}

With this example, the defined constructor for foo<T, int> is not considered when attempting to instantiate bar.

If I use a derived class for foo_int instead of a type alias, the same example works, but it's not really what I am trying to achieve. Similarly, I can make it work by replacing foo_int(1.0) with foo_int<double>(1.0), but I would like to avoid that.

1

There are 1 best solutions below

0
StoryTeller - Unslander Monica On

Constructors from (partial) specializations aren't taken into account when doing class template arguments deduction (even if it's via the new support for alias templates in C++20, which is not without its own limitations).

Since your primary template is incomplete, you can add an explicit deduction guide to make it work. For example

template <typename T>
using foo_int = foo<T, int>;

template <typename T>
foo(T) -> foo<T, int>;

That's an imperfect solution however, if you have multiple aliases. Because a deduction guide can only specify the second parameter once. In which case I'd suggest you go back to using inheritance instead of aliases (since they can have independent CTAD processes).