Разрешен ли вызов оператора перегрузки-> во время компиляции? - PullRequest
3 голосов
/ 25 мая 2010

когда я пытался скомпилировать код: (примечание: func и func2 не опечатка)

struct S
{
    void func2() {}
};

class O
{
public:
    inline S* operator->() const;
private:
    S* ses;
};

inline S* O::operator->() const
{
    return ses;
}

int main()
{
    O object;
    object->func();
    return 0;
}

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

D:\code>g++ operatorp.cpp -S -o operatorp.exe
operatorp.cpp: In function `int main()':
operatorp.cpp:27: error: 'struct S' has no member named 'func'

похоже, что вызов перегруженной функции "operator->" выполняется во время компиляции? Я добавил опцию "-S" только для компиляции.

Ответы [ 5 ]

10 голосов
/ 25 мая 2010

Да, он обрабатывается как обычный вызов функции, просто вызывается перегруженным оператором.Компилятор проверяет все правильно во время компиляции.C ++ не похож на динамические языки, где он ожидает, пока время выполнения сработает, если p->mynonexistantfunction() является допустимым именем функции или нет, компилятор отклонит код во время компиляции, если имя функции не существует.

В этом случае это выглядит как опечатка, у S есть функция func2(), но ваш код вызывает func().

3 голосов
/ 25 мая 2010

В структуре S вы объявили func2 (), но в main вы пытаетесь вызвать func ().

попытка int main() { O object; object->func2(); return 0; }

2 голосов
/ 25 мая 2010

В языке C ++ вы не можете выбрать члена класса по имени во время выполнения. Выбор члена класса (по непосредственному имени члена) всегда выполняется во время компиляции. Обойти это невозможно.

Если вы хотите реализовать выбор элементов во время выполнения, вы можете использовать только операторы .* и ->* (первый - без перегрузки). Тем не менее, эти операторы во встроенной форме ожидают указателей на члены в качестве своих правых операндов. Если вы хотите выбрать что-то по имени (в виде строки), вы можете перегрузить ->*, чтобы заставить его принимать другой тип аргумента, но в любом случае вам придется реализовать преобразование строки в фактический член вручную. Однако для функций-членов (в отличие от членов-данных) это обычно довольно сложно.

2 голосов
/ 25 мая 2010

Да, компилятор проверяет операторы по результату, как любая другая функция.

В этом случае, если у вас было, например,

S* foo() { ... }

(foo())->func();

результат будет таким же.

1 голос
/ 25 мая 2010

object->func() - просто синтаксический сахар для object->operator->()->func() для пользовательских типов. Поскольку O::operator->() дает S*, для этого требуется существование метода S::func() во время компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...