为什么模板<T>而不是模板<>可以在命名空间块之外定义?

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

本文关键字:gt lt 命名空间 定义 为什么      更新时间:2023-10-16

以下是一些不编译的代码。

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;
}

错误为:"template int ns::foo::bar(T*

这里有一个编译的版本:

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;
    }
}

为什么第二个定义必须在namespace ns {}块中,而第一个定义是用限定名称定义的?这只是语言设计中的疏忽,还是有原因?

这里的问题不是定义,而是声明。不能从不同的命名空间在命名空间中注入声明,因此必须在适当的命名空间中声明专门化,然后才能在任何封闭命名空间中定义

基本模板的定义可以在外部命名空间中完成,因为它已经被声明,所以外部命名空间中的代码提供了一个定义,但不会向命名空间中注入任何声明。

尝试:

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;
}