Why can template<T> but not template<> be defined outside of a namespace block?

匿名 (未验证) 提交于 2019-12-03 08:33:39

问题:

Here is some code which does not compile.

namespace ns {     class foo     {         template <typename T> int bar (T *);     }; }  template <typename T> int ns :: foo :: bar (T*) // this is OK {     return 0; }  template <> int ns :: foo :: bar <int> (int *) // this is an error {     return 1; }

The error is: "specialisation of ‘template int ns::foo::bar(T*)’ in different namespace [-fpermissive] from definition of ‘template int ns::foo::bar(T*)"

Here is a version which does compile:

namespace ns {     class foo     {         template <typename T> int bar (T *);     }; }  template <typename T> int ns :: foo :: bar (T*) {     return 0; }  namespace ns {     template <>     int foo :: bar <int> (int *)     {         return 1;     } }

Why does the second definition have to be in a namespace ns {} block when the first one is quite happily defined with a qualified name? Is it just an oversight in the language design or is there a reason for this?

回答1:

The problem here is not the definition, but the declaration. You cannot inject a declaration in a namespace from a different namespace, so the specialization must be declared in the appropriate namespace before it can be defined in any enclosing namespace.

The definition of the base template can be done in the outer namespace because it has already been declared, so the code in the outer namespace provides a definition but does not inject any declaration into the namespace.

Try:

namespace ns {     class foo     {         template <typename T> int bar (T *);     };     template <>     int foo::bar<int>(int*); // declaration } template <typename T> int ns :: foo :: bar (T*) {     return 0; } template <> int ns :: foo :: bar <int> (int *) {     return 1; }


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!