Шаблон с указателем на функцию-член => различные сообщения об ошибках с VC ++ 2017 и gcc 5.1 - PullRequest
0 голосов
/ 24 сентября 2019

Я застрял в следующем коде и буду признателен за любые предложения

template <typename T, class U>
class A {
public:
    // Pointer to member function of U
    typedef void (U::*MemberPtr)(T);
    // Constructor
    Action(std::string action_name, MemberPtr func) {
        this->fPtr = func;
    } 
    // Invoke member function of U passed in constructor
    void invoke(T argument) {
        fPtr(argument); // <-- VC++ error C2064: Expression does not evaluate to a function call, ok for gcc  (Q1)
    }

private:
    MemberPtr fPtr;

Этот шаблон выше используется в классе 'C'

class C; // forward decl

class C {
    void dummyDbl(double arg);

    Action<double, C> dblAction = Action<double, C>("x", &C::dummyDbl);
    // gcc (5.1.0 )complains: (VS 2017 is fine with that) (Q2)
    // Action<double, C>("x", &C::dummyDbl);
    //                ^
    // error: expected unqualified-id before '>' token

Мои вопросы к аудитории

  1. Почему компилятор (VC ++ 2017) жалуется на вызов функции, в то время как gcc с этим справляется (см. Q1)?Чего мне не хватает?
  2. Есть идеи, почему gcc выдает ошибку, в то время как VC ++ хорошо работает с decl (Q2)?
  3. Есть ли возможность опустить второй параметр шаблона , но ограничивая область действия функциями-членами данного класса (например, Action внутри класса X не должен вызывать функцию-член класса Y )?

Заранее спасибо, Оливер

1 Ответ

2 голосов
/ 24 сентября 2019

Код

void invoke(T argument) {
    fPtr(argument); // <-- VC++ error C2064: Expression does not evaluate to a function call, ok for gcc  (Q1)
}

Неправильно сформирован.Вам нужен объект для вызова функции-члена, а у вас его нет здесь.Причина, по которой вы видите ошибку в MSVC, но не в GCC, скорее всего, связана с разницей в обработке шаблона.Полный код необходим, чтобы указать точную причину, но это, вероятно, было бы спорным упражнением - независимо от внешнего вида, код плох для любого компилятора и должен быть исправлен.

Второй код

Action<double, C> dblAction = Action<double, C>("x", &C::dummyDbl);

выглядит как ошибка в gcc5, правильно компилируется в gcc6.Он также правильно компилируется в CLang, так как 3.4.1

Этот код компилируется везде:

A<double, C> dblAction{"x", &C::dummyDbl};

Извините, вопрос 3 неясен, и лучший формат для SO - one вопрос за пост.Поэтому я предлагаю разделить вопрос 3 на отдельный пост.

...