Reputation: 855
I noticed a different behavior between gcc
9.2.0 and clang++
9.0.1. My code is as follows
//header.hh
...
template <typename T>
class Outer {
...
public:
template <typename S>
class Inner;
...
};
template <typename T>
template <typename S>
class Inner {
...
Inner& func();
...
};
then, since the function func()
is implemented in another file
//implementation.cc
template <typename T>
template <typename S>
Outer<T>::Inner<S>& Outer<T>::Inner<S>::func() {
...
};
Now, if I use g++
the compilation is OK. If I use clang++
I get
src/implementation.cc:6:1: error: missing 'typename' prior to dependent type template name 'Outer<T>::Inner'
Outer<T>::Inner<S>& Outer<T>::Inner<S>::func() {
^
1 error generated.
However if I follow its suggestion and use
typename Outer<T>::Inner<S>& Outer<T>::Inner<S>::func()
I got another error:
src/implementation.cc:6:21: error: use 'template' keyword to treat 'Inner' as
a dependent template name typename Outer<T>::Inner<S>& Outer<T>
::Inner<S>::func() {
And now its suggestion seems very weird.
Upvotes: 0
Views: 122
Reputation: 6144
The correct syntax would be the following:
template <typename T>
template <typename S>
typename Outer<T>::template Inner<S> &Outer<T>::Inner<S>::func() {
...
}
You can find the full explanation for this syntax in this question.
However, a simpler and also valid syntax would be this:
template <typename T>
template <typename S>
auto Outer<T>::Inner<S>::func() -> Inner& {
...
}
By using the trailing return type syntax in the example above you can take advantage of the fact that the name resolution scope is within Outer<T>::Inner<S>
at that point so you can use the injected class name of the Inner
.
Upvotes: 1