2016-03-10 3 views
5

Сегодня мой друг и я много боролись с глупой ошибкой, и я заставляю задуматься о том, как параметры шаблона работают на C++. Рассмотрим следующий код, где я пытаюсь частично специализировать класс attr<MyClass<I>> где I является unsigned int, хотя MyClass ожидает int параметр:Параметр шаблона C++ и частичная специализация: сильная или слабая типизация?

#include <iostream> 

template<int I> 
class MyClass 
{ 

}; 

template<typename T> 
struct attr; 

template<unsigned int I> 
struct attr<MyClass<I>> 
{ 

}; 

int main(int argc, char *argv[]) 
{ 
    attr<MyClass<1>> att; 
    return 0; 
} 

g++ терпит неудачу с сообщением об ошибке

main.cpp: In function ‘int main(int, char**)’: 
main.cpp:20:22: erreur : aggregate ‘attr<MyClass<1> > att’ has incomplete type and cannot be defined 
    attr<MyClass<1>> att; 

И clang компилирует его (только предупреждение из-за того, что att не используется).

Так мне было интересно:

  • есть что-нибудь в спецификации, которая будет править в пользу одного или другого?

  • можно ли сказать, что набор параметров шаблона clang слабее, чем g++?

ответ

1

Да, GCC правильно отклоняет, по крайней мере, согласно действующим стандартам. Возможно, люди Клэнга здесь представили какой-то отчет о дефектах, я бы не знал.

http://eel.is/c++draft/temp.deduct.type#17

Если P имеет форму, которая содержит <i>, и если тип соответствующего значения А отличается от типа I, вычет терпит неудачу. Если P имеет форму, содержащую [i], и если тип i не является интегральным типом, то вывод не выполняется.

Их тестовый тест в testuite проверяет это только на функции, для которых они, по-видимому, излучают разумные сообщения об ошибках: https://github.com/llvm-mirror/clang/blob/master/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp.

Кроме того, поскольку частичная специализация никогда не может быть выведена, мы также сталкиваемся с http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#549, в которой спрашивается, должны ли такие конструкции быть отклонены заранее. На мой взгляд, http://eel.is/c++draft/temp.res#8 может быть применен, если вы хотите:

«Зная, какие имена являются имена типов позволяет синтаксис каждого шаблона для проверки Программа плохо формируется, нет диагностики требуется, если:.

  • не действует специализации может быть сгенерирован для шаблона и шаблон не создается экземпляр, или ...»

Там нет никакого законного способа вызвать экземпляр этого шаблона, поэтому вы с ould утверждают, что для него не может быть создана действительная специализация. В соответствии с этой интерпретацией поведение не определено и что-то законно.

Смежные вопросы