1

I don't understand why it succeeds when calling the static method template directly, but not when calling it through the function template.

#include <iostream>
#include <type_traits>

template <typename A>
class Test {
public:         
    template <typename B>
    static void test() {
        if (std::is_same<A, B>::value)
            std::cout << "Type A and Type B are the same\n";
        else
            std::cout << "Type A and Type B are not the same\n";
    }       
};

template <typename C, typename D>
void test() {
    Test<C>::test<D>();
}

int main(int argc, char* argv[]) {
    Test<int>::test<int>();
    Test<int>::test<char>();

    test<int, char>();
    test<int, int>();

    return 0;
}

Compiled with the command line:

g++ -std=c++11 test.cpp

Using:

$ g++ --version
g++ (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

And got these errors:

test.cpp: In function ‘void test()’:
test.cpp:18:20: error: expected primary-expression before ‘>’ token
     Test<C>::test<D>();
                    ^
test.cpp:18:22: error: expected primary-expression before ‘)’ token
     Test<C>::test<D>();
                      ^ 

2 Answers2

2

test is a dependent name here:

template <typename C, typename D>
void test() {
    Test<C>::test<D>();
           ^^^^^^^^^
}

As such, you need to inform the compiler that it's a template:

template <typename C, typename D>
void test() {
    Test<C>::template test<D>();
}
Barry
  • 286,269
  • 29
  • 621
  • 977
1

For dependent names you need to tell the compiler that the name is a template:

Test<C>::template test<D>();
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380