If I want to use the private member function of template class A from template class B, you can usually solve it by declaring a friend in class A. In the following code, it doesn't work when enum type is used as an argument. If i know how to deal with it, could you please teach me?

'funcA' is a private member of'A<int>'
Corresponding source code
template<typename T>
class B {
    enum type {a, b, c};
    void funcB (type);
template<typename T>
class A {
    friend void B<T>:: funcB (B<T>:: type);
    static void funcA () {} // I want to use this function
template<typename T>
void B<T>:: funcB (type) {
    A<T>:: funcA ();/// I want to use it here
int main () {
    b.funcB (B<int>:: type :: a);
    return 0;
What I tried

If i declare it as funcB (), define it, and eliminate the argument, no error will occur.

Supplementary information (FW/tool version, etc.)

c ++ 17

  • Answer # 1

    typenameIs required

    -friend void B<T>:: funcB (B<T>:: type;
    + friend void B<T>:: funcB (typename B<T>:: type);

    C ++ keywords: typename

    It can be used as an alternative to class to declare type template arguments and template template arguments (C ++ 17 and above) in template declarations.

    It can be used in a template declaration or definition to declare that the dependent qualified name is a type.

    You can use typename in front of an independent qualified type name (less than C ++ 11) in a template declaration or definition. In this case, it has no effect.

    For type requirements in requirements (C ++ 20 and above)

    I'm sorry, the above was the reason why compiling with g ++ did not work.
    In g ++typenameWithouterror:'B :: type' is not a typeWill result in an error.

    It feels like a clang bug,
    If you do the following, both clang and g ++ will compile.

    template<typename T, class ClassB = B<T >>
    class A {
        friend void ClassB :: funcB (typename ClassB :: type);
        static void funcA () {}

    As you commented, the compilation will pass even if you do the following.

    template<typename T>
    class A {
        using ClassB = B<T>;
        friend void ClassB :: funcB (typename ClassB :: type);
        static void funcA () {}