Указатели на функции-члены - не удается понять сообщение об ошибке g ++ - PullRequest
0 голосов
/ 07 мая 2020

Я пишу систему отчетности, включая класс - Datum - с различными точками данных и класс - Statisti c - с метаданными о строках отчета. Метаданные включают указатели на функции-члены Datum для получения и установки данных.

class Statistic
{
    .
    .
    .
        double (Datum::*getter) () const;
        void (Datum::*setter) (const double);
    .
    .
    .
}

Я написал конструктор для Statisti c:

Statistic::Statistic (
        double Datum::*a_getter (),
        void (Datum::*a_setter)(const double))
{
    getter  = a_getter;
    setter  = a_setter;
}

Это не компилируется; g ++ выводит ошибку

не может преобразовать 'double Datum :: * (*) ()' в 'double (Datum :: *) () const' в присваивании

[Примечание: между второй звездочкой и скобками нет пробелов, но если я их оставлю, звездочка не будет отображаться после форматирования]

в строке, которая присваивается m_getter.

Я плохо умею интерпретировать указатели на функции и не могу понять, что на самом деле написал. Кажется, я объявил m_getter указателем на функцию-член Datum, не принимающую аргументов и возвращающую двойное значение. Я не уверен, что имел в виду const. Это примерно то, что я хочу - я хотел бы быть константным указателем на функцию-член const Datum, не принимающую аргументов и возвращающую двойное значение. (Я понимаю, что это означает, что мне нужно инициализировать его в конструкторе, а не присваивать ему.) Я не могу понять, что я в итоге сказал, что getter - это, g ++ испускает больше * s, чем я могу справиться with.

Как мне объявить m_getter и мой конструктор?

Ответы [ 2 ]

2 голосов
/ 07 мая 2020

double Datum::*getter () объявляет getter как функцию, которая не принимает аргументов и возвращает указатель-на-член- Datum, указывающий на double - a double Datum::*.

Используйте тот же синтаксис, что и в объявлении члена; double (Datum::*getter) ().

Или даже лучше: используйте псевдоним типа.

class Statistc
{
    using getter_function = double (Datum::*)() const;
    using setter_function = void (Datum::*)(double);

    getter_function m_getter;
    setter_function m_setter;

    // ...
};
Statistic::Statistic (
        getter_function getter,
        setter_function setter)
    : m_getter(getter),
      m_setter(setter)
{
}
1 голос
/ 07 мая 2020

Сверху с дополнительными пробелами:

double * somepointer;
         ^^^^^^^^^^^ a pointer to double
double Datum::* otherpointer;
                ^^^^^^^^^^^^ a pointer to double within `Datum`
                             The double that we point to is within Datum
double Datum::*   getter();  
                  ^^^^^^ - a declaration of a function named `getter`
                           that returns a pointer to double within `Datum`
                           and takes no arguments
double (Datum::*   getter2)();
                   ^^^^^^^ - a function pointer to member function
                             can point to a function within `Datum`
                             can be called using an instance of `Datum`
                             that returns double and takes no arguments
double (Datum::*   getter3)() const;
                   ^^^^^^^ - a function pointer to member function
                             can point to a function within `Datum`
                             can be called using an instance of `const Datum`
                             that returns double and takes no arguments

Вы можете:

class Statistic
{
    double (Datum::*m_getter) () const;
    void (Datum::*m_setter) (const double);

    Statistic::Statistic (
            double (Datum::*getter)() const,
            void (Datum::*setter)(const double))
    {
        m_getter  = getter;
        m_setter  = setter;
    }
};
...