Fully qualified name and type alias as return value

I have an header file, for which I want to write the definition of the function not right after the declaration. The only problem is that the return type of such function is defined thought `using`, and when I try to compile my code I got a compiler error. I've spent lots of time trying to understand what's the problem. Let me give a minimal reproducible example in order to clarify this:

Header file **Foo.hpp**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    #ifndef foo_hpp
    #define foo_hpp
    
    #include <iostream>
    #include <utility>
    
    template <typename T>
    class Foo{
    private:
        int x;
    public:
        using pairtype = std::pair<int,int>;
        Foo(int xx):x{xx}{}
        
        pairtype Bar();
        
    };
    
    
    template<typename T>
    Foo<T>::pairtype Foo<T>::Bar(){ #<--!! HERE
        std::cout << "It's working! :-) " <<"\n";
        return pairtype(2,2);
    }
    
    #endif /* foo_hpp */

and the following is the **main.cpp** file, where I simply invoke the function:
1
2
3
4
5
6
7
8
    #include "foo.hpp"
    
    int main(){
        
        Foo<int> my_obj(96);
        Foo<int>::pairtype p = my_obj.Bar();
        return 0;
    }



Running this with g++ -o foo -Wall -Wextra -std=c++14 foo.cpp gives the following error.

> ./foo.hpp:21:1: error: missing 'typename' prior to
> dependent type
> name 'Foo<T>::pairtype' Foo<T>::pairtype Foo<T>::Bar(){ ^~~~~~~~~~~~~~~~ typename


Now to my question: I've seen that if I put, as suggested, `typename`, then it works. However, I don't understand why it doesn't work with the `class` keyword
Last edited on
Now to my question: I've seen that if I put, as suggested, `typename`, then it works. However, I don't understand why it doesn't work with the `class` keyword

You're required to write typename by fiat. There is no fundamental reason that disambiguation is necessary in this case.
@mbozzi

I've seen similar codes where people write class instead of typedef: however, in my case this doesn't work. Could you explain me why?
Last edited on
Could you explain me why?

It's typename, not typedef.
There is only one case I can think of where typename can be replaced with class. That is in template parameters:
1
2
template <typename T> void f(); // ok 
template <class T> void g(); // ok 

Disambiguation of dependent types (a different situation) can only be done with typename, although MSVC has (had?) a minor related bug.
Last edited on
I've just tried to compile their code (with clang 12.0), and I always got compiler error where they use keyword class, like this

1
2
3
class Foo<T>::pairtype Foo<T>::Bar(){
//body of the function
}


instead of
1
2
3
typename Foo<T>::pairtype Foo<T>::Bar(){
//body of the function
}


which runs fine, of course. I honestly can't understand why it runs fine for them. Nevermind. :-)

Thanks guys for your answers :-)
Last edited on
Topic archived. No new replies allowed.