Reputation: 118021
If I have a class A
that is templated on type T
, and that class has a method Foo
that is templated on type U
template <class T>
class A
{
public:
template <class U>
void Foo();
};
To define that function outside the class I need two template statements like so
template <class T>
template <class U>
void A<T>::Foo() {} // this compiles
The following does not compile
template <class T, class U>
void A<T>::Foo() {} // this does not compile
with the error
prog.cpp:10:6: error: no declaration matches ‘void A<T>::Foo()’
void A<T>::Foo() {}
^~~~
prog.cpp:6:7: note: candidate is: ‘template<class T> template<class U> void A<T>::Foo()’
void Foo();
^~~
prog.cpp:2:7: note: ‘class A<T>’ defined here
class A
^
Is there a more terse/compact way to define both template types in a single statement like above?
Upvotes: 2
Views: 89
Reputation: 73236
Is there a more terse/compact way to define both template types in a single statement like above?
As of C++20, you can make use of abbreviated function templates, which allows declaring as well (later) defining function templates in a more compact manner. This approach, however, is restricted to type template parameters that can be inferred via template argument deduction, as the placeholder types (auto
or SomeConcept auto
) must appear in the parameter list of an abbreviated function template declaration.
template <typename T>
struct A {
void foo(auto);
};
template <typename T>
void A<T>::foo(auto) {}
Note that void foo(auto)
is equivalent to template<typename T> void foo(T)
, as the former declares a function template with a single (invented) template parameter corresponding to the single placeholder type. This means that mixing of the abbreviated function template syntax and the classic function template syntax for the same entity is allowed (e.g. using one syntax for declaring it and the other syntax for defining it):
template <typename T>
struct A {
template <typename U>
void foo(U);
};
template <typename T>
void A<T>::foo(auto) {}
template <typename T>
struct B {
template <typename U>
void foo(U, auto);
};
template <typename T>
void B<T>::foo(auto, auto) {}
Upvotes: 4