Компилятор C ++ не проверяет, существует ли метод в классе шаблона - PullRequest
9 голосов
/ 04 июля 2019

Я сталкивался со следующей программой в C++:

template <class T>
class Val {
protected:
    T x0, x;
public:
    Val(T t = 1) : x0(t), x(1) {}
    T val() { return x; }
    void promote() { this->promote_value(); }
};

По какой-то причине Val<int>(4).val(); работает нормально, хотя нет способа promote_value(). Я пытался удалить шаблоны:

class OtherVal {
protected:
    int x0, x;
public:
    OtherVal (int t = 1) : x0(t), x(1) {}
    int val() { return x; }
    void promote() { this->promote_value(); }
};

Но теперь я получаю сообщение об ошибке:

ошибка: у класса OtherVal нет члена с именем promo_value; Вы имели в виду «продвигать»?

Почему C++ ведет себя так?

Ответы [ 2 ]

12 голосов
/ 04 июля 2019

Методы класса шаблона не создаются до тех пор, пока они не будут использованы.Как только вы попытаетесь позвонить promote() или даже получить его адрес, подобный этому &Val<int>::promote, вы получите ошибку.

Из стандарта C ++:

§ 17.8.1.10 Anреализация не должна неявно создавать экземпляр шаблона функции, шаблона переменной, шаблона элемента, не виртуальной функции-члена, класса-члена, статического члена-данных шаблона класса или подстановки оператора constexpr if (9.4.1)Если только такое создание не требуется.

8 голосов
/ 04 июля 2019

Шаблоны всегда работали таким образом, главным образом для облегчения их использования.

Поскольку Val<int>(4).val(); не вызывает promote, эта функция не скомпилирована для вашего конкретного экземпляра этого шаблона, поэтому компилятор не выдает диагностику.

Многие методы метапрограммирования зависят от этого поведения.

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