Ошибка компиляции: неразрешенный тип перегруженной функции

Я пытаюсь скомпилировать с g ++ 4.7.2 следующее:

template <typename T>
struct A {
    struct B {
        T t;

        template<T B::*M>
        T get() {
            return this->*M;
        }
    };

    B b;

    T get() {
        return b.get<&B::t>();
    }
};


int main() {
    A<int> a;
    a.get();
}

Это дает мне

test.cpp: In member function ‘T A<T>::get()’:
test.cpp:15:23: error: expected primary-expression before ‘)’ token
test.cpp: In instantiation of ‘T A<T>::get() [with T = int]’:
test.cpp:22:8:   required from here
test.cpp:15:23: error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘int A<int>::B::*’ to binary ‘operator<’

Почему?

Спасибо.


person Paul Draper    schedule 28.03.2013    source источник


Ответы (1)


Вам необходимо использовать template устранитель неоднозначности:

return b.template get<&B::t>();

Без него при разборе выражения:

b.get<&B::t>();

Компилятор не может сказать, должен ли он интерпретировать get как имя переменной-члена, за которым следует знак < (меньше чем), или как создание экземпляра шаблона функции-члена с именем get.

Хотя мы знаем, каково предполагаемое значение нашего выражения, компилятор не может, по крайней мере, не до того, как произойдет создание экземпляра - и синтаксический анализ выполняется, даже если ваша функция никогда не создается.

person Andy Prowl    schedule 28.03.2013
comment
И когда вы знаете C ++ ... Когда я должен использовать устранение неоднозначности в шаблоне? (Я просто искал, но, похоже, не нашел хорошего ответа по этому поводу.) - person Paul Draper; 29.03.2013
comment
@PaulDraper: На самом деле я нашел этот Q&A, который должен хорошо это объяснить. - person Andy Prowl; 29.03.2013
comment
Превосходно. Это также включает объяснение для typename, которое я также не полностью понял. - person Paul Draper; 29.03.2013
comment
@PaulDraper: Хорошо, рад, что помог! - person Andy Prowl; 29.03.2013