Kevlar
Kevlar

Reputation: 396

Template argument deduction with alias template partially specializing a class template

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.

Upvotes: 0

Views: 129

Answers (1)

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).

Upvotes: 0

Related Questions