Когда требуется создание определения шаблона функции? - PullRequest
0 голосов
/ 18 сентября 2018

После прочтения ответа на этот вопрос я все еще задаю вопрос.Ответ говорит о расположении точки создания экземпляра, как определено в [temp.point], но не оценивается, требуется ли создание экземпляров.

[temp.inst] указывает, когда шаблон функциитребуется конкретизация специализации, общее правило:

Реализация не должна неявно создавать экземпляр шаблона функции, шаблона переменной, шаблона элемента, не виртуальной функции-члена, класса-члена, [...], , если такое создание не требуется.

Более того, в некоторых параграфах этого раздела стандарта создание объявления и определение определения рассматриваются отдельно.

Давайте рассмотрим этот код:

static void Yeap0(int);

template <class T>
void Yeap(T a){
    Yop(a);
}

template <class T>
auto Yeap2(T a){
    Yop(a);
    return 0;
}
namespace x{
    struct y{};
}

int main() {
    Yeap0(0);//ok no definition required here
    x::y ax{};
    Yeap(ax); //the declaration is sufficient, 
    Yeap2(ax); //need to deduce auto => definition required
               //compilation error
    return 0;
}

namespace x{
    void Yop(y){}
}

static void Yeap0(int){}

Gcc, Clang и MSVC выдают только ошибку для Yeap2(ax), жалуясь, что Yop не определен в момент создания Yeap2.

Но эта ошибка не генерируется для Yeap(ax).Исходя из базовых соображений, это кажется логичным, необходимо только объявление, так как для функции non template Yeap0.

Но лекция [temp.inst] / 4 позволила мне озадачиться.Можно понять, что создание экземпляра Yeap также требуется.Но кажется, что компиляторы выбрали более умный путь.

Является ли поведение компиляторов расширением?


Примечание. Я не приму ответ "нет необходимости в диагностике".Это было бы оскорблением для интеллекта: можно ли поверить, что 3 компилятора позаботились о выключении диагностики для случая, подобного Yeap(ax), но не для Yeap2(ax)?

1 Ответ

0 голосов
/ 25 сентября 2018

Компилятор действительно жалуется на то, что функция возвращает auto.

В случае auto вы действительно нажмете

, если не требуется такой реализации.

, которая должна исходить оттребование dcl.spec.auto .

Чтобы проверить, что оценку вы можете заменить в своем коде Yeap2 на:

template <class T>
auto Yeap2(T a){
    Yeap(a);
    return 0;
}

и ошибки компиляции нет.

...