Правильное использование шаблонного объекта c шаблонном методом в методе шаблонного класса

При создании шаблонного объекта с шаблонном методом в методе шаблонного класса, с параметром класса возникает ошибка. При этом если указать в качестве параметра объекта явно тип (не параметр класса), то все нормально. Почему так происходит? Исходный код:

#include <iostream>

template< class N >
class A {       
    public:
        template< class M >
        void fun(N n, M m) {
            std::cout << "Hello World! " << n << " " << m << std::endl;
        }
};

template< class N, class M >
class B {
    public:
        void fun(N n, M m) {
        A< N > a;   // Почему если здесь вместо N написать int, то все нормально, а если как есть то ошибка?
        a.fun< M >(n, m);
    }
};

int main() {
    B< int, int > b;
    b.fun(1, 2);
    return 0;
}

Ошибка при компиляции:

main.cpp: In member function ‘void B<N, M>::fun(N, M)’:
main.cpp:28:11: error: expected primary-expression before ‘>’ token
  a.fun< M >(n, m);

С уважением, Александр


Ответы (2 шт):

Автор решения: Harry

Да не указывайте ничего :), компилятор сам все выведет:

void fun(N n, M m) {
    A< N > a;
    a.fun(n, m);
}

См. https://ideone.com/PMMgXP

И, кстати, метка "шаблоны", если вы читали описание, относится к шаблонам проектирования.

→ Ссылка
Автор решения: user496704

Надо искользовать ключевое слово template, чтобы уверить компилятор, что мы вызываем шаблонную функцию:

a.template fun<M>(n, m);

Аналогично тому, как мы указываем шаблонный тип с помощью typename для зависимых типов:

typename DependantType<T>::type x;

вместо:

DependantType<T>::type x;
→ Ссылка