шаблонный вывод параметров шаблона: три разных компилятора три разных поведения - PullRequest
3 голосов
/ 27 февраля 2020

Рассмотрим следующую демонстрационную программу.

#include <iostream>

template <class T1, class T2 = T1>
struct A 
{
};

template <template <class> class T>
void f( const T<int> & )
{
    std::cout << "f( const T<int> & )\n";
}

int main()
{
    A<int> a;

    f( a );
    f<A>( a );
}

Компилятор g cc HEAD 10.0.1 20200 успешно компилирует программу и вывод программы составляет

f( const T<int> & )
f( const T<int> & )

Компилятор clang HEAD 11.0.0 не компилирует ни первый вызов функции f, ни второй вызов функции f. Он выдает сообщение об ошибке, подобное

prog.cc:25:5: error: no matching function for call to 'f'
    f( a );
    ^
prog.cc:9:6: note: candidate template ignored: substitution failure: template template argument has different template parameters than its corresponding template template parameter
void f( const T<int> & )
     ^
1 error generated.

Компилятор Visual C ++ 2019 не компилирует первый вызов функции

f( a );

, но успешно компилирует вторую функцию call

f<A>( a );

Таким образом, возникает вопрос, какой компилятор ведет себя в соответствии со стандартом C ++ 17 (или, может быть, C ++ 20)?

1 Ответ

2 голосов
/ 28 февраля 2020

Это CWG 150 , которая была разрешена с помощью DR P0522 , которая находится в C ++ 17.

Обратите внимание, что g ++ отклоняет программу (оба вызова на f) в режиме C ++ 14 (-std=c++14, et c).

Clang принимает вашу программу только в режиме не по умолчанию, включенном с флагом -frelaxed-template-template-args, в соответствии с после обоснования :

Несмотря на то, что это разрешение для отчета о дефектах, эта функция по умолчанию отключена во всех языковых версиях и может быть включена явно с флагом -frelaxed-template-template-args в Лязг 4 года. Изменению в стандарте не хватает соответствующего изменения для частичного упорядочения шаблона, что приводит к ошибкам неоднозначности для разумного и ранее действительного кода. Ожидается, что эта проблема будет исправлена ​​в ближайшее время.

Я не уверен, какие именно ошибки двусмысленности беспокоит Кланг, но вероятным примером будет этот недавний вопрос .

Что касается MSV C, он отклоняет второй вызов f в режиме C ++ 14 (-std:c++14), принимая его в режиме C ++ 17 (-std:c++17), демонстрируя, что они считают второй вызов должен быть покрыт P0522 согласно таблице соответствия ; К сожалению, они, похоже, не рассматривали случай первого вызова, когда аргумент шаблона шаблона выводится из аргумента функции, что эквивалентно первому случаю в CWG 150. Я подал проблему в сообществе разработчиков.

...