This code compiles
template<typename T>
struct A {
struct Inner {} inner;
void foo(Inner in);
};
template<typename T>
void A<T>::foo(typename A<T>::Inner in) {
}
int main() {
A<int> a;
a.foo(a.inner);
}
And it won't if I change typename A<T>::Inner
to an alias template like
template<typename T>
using AInner = typename A<T>::Inner;
template<typename T>
void A<T>::foo(AInner<T> bar) {
}
The compiler complains that error: no declaration matches ‘void A<T>::foo(AInner<T>)’
I'm not quite familiar with the rules of alias templates. Aren't they the same type?
Edit: Here is the full demo:
// hello.cpp
template<typename T>
struct A {
struct Inner {} inner;
void foo(Inner in);
};
template<typename T>
using AInner = typename A<T>::Inner;
template<typename T>
void A<T>::foo(AInner<T> in) {
}
int main() {
A<int> a;
a.foo(a.inner);
}
And I compile it with g++ (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0
The output:
hello.cpp:11:6: error: no declaration matches ‘void A<T>::foo(AInner<T>)’
11 | void A<T>::foo(AInner<T> in) {
| ^~~~
hello.cpp:4:10: note: candidate is: ‘void A<T>::foo(A<T>::Inner)’
4 | void foo(Inner in);
| ^~~
hello.cpp:2:8: note: ‘struct A<T>’ defined here
2 | struct A {
|
Your code is correct. This is a known bug of g++, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101789
Other compilers are fine with this code, online demo: https://gcc.godbolt.org/z/5Pv9KW8vj