Search code examples
c++g++compiler-bugtemplate-aliases

Why doesn't the alias template in function parameter match the nested type it refers to?


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 {
      |

Solution

  • 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