Форум » C/C++ » Явная специализация (explicit specialization) шаблонной функции и баг (bug) GCC » Ответить

Явная специализация (explicit specialization) шаблонной функции и баг (bug) GCC

Сыроежка: В новом стандарте C++ 2011 произошли изменения в описании относительно явной специализации шаблонных функций по сравнению с предыдущим стандартом C++ 2003. Ранее в стандарте C++ 2003 в параграфе №2 раздела 14.7.3 Explicit specialization было написано следующее: [quote] 2 An explicit specialization shall be declared in the namespace of which the template is a member, or, for member templates, in the namespace of which the enclosing class or enclosing class template is a member. An explicit specialization of a member function, member class or static data member of a class template shall be declared in the namespace of which the class template is a member. Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later in the namespace in which the explicit specialization was declared, or in a namespace that encloses the one in which the explicit specialization was declared. [/quote] Другими словами, если первое объявление явной специализации шаблонной функции является одновременно и ее определением, то это определение должно быть задано в том же пространстве имен, в котором объявлен исходной шаблон. В стандарте C++ 2011 этот параграф был изменен: [quote] 2 An explicit specialization shall be declared in a namespace enclosing the specialized template. An explicit specialization whose declarator-id is not qualified shall be declared in the nearest enclosing namespace of the template, or, if the namespace is inline (7.3.1), any namespace from its enclosing namespace set. Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later (7.3.1.2). [/quote] То есть теперь необязательно объявлять явную специализацию шаблонной функции в том же самом пространстве имен, где был объявлен исходный шаблон. Это можно сделать в охватывающем пространстве имен, квалифицировав имя шаблона. Следовательно и определение явной специализации шаблонной функции, которое одновременно является и ее первым объявлением можно делать в охватывающем пространстве имен. Стандарт C++2011 смягчил требования к объявлению явной специализации шаблонной функции. На это стоит обратить внимание. Однако в связи с этим был обнаружен баг компилятора GCC, который несложно воспроизвести на сайте онлайновых компиляторов www.ideone.com, если запустить на компиляцию следующую простую программу: [pre2] #include <iostream> #include <utility> #include <string> namespace N { template <typename T1, typename T2> void f( const T1 &, const T2 & ) { } } template <> void N::f( const std::pair<int, std::string>& lhs, const std::pair<int, std::string>& rhs ) { } int main() { return 0; } [/pre2] Компилятор GCC выдаст следующее сообщение об ошибке: [quote] prog.cpp:18:48: error: specialization of ‘template<class T1, class T2> void N::f(const T1&, const T2&)’ in different namespace [-fpermissive] const std::pair<int, std::string>& rhs ) ^ prog.cpp:10:6: error: from definition of ‘template<class T1, class T2> void N::f(const T1&, const T2&)’ [-fpermissive] void f( const T1 &, const T2 & ) ^ [/quote] Интересно отметить, что этот код успешно компилируется более старым компилятором MS VC++ 2010. Хочу предупредить, что, естественно, эта информация о баге компилятора актуальна на день написания этого сообщения. Так что когда вы будете его читать, вполне возможно, что этот баг компилятора уже исправлен.

Ответов - 0



полная версия страницы