20

这是一些无法编译的代码。

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

错误是:“模板 int ns::foo::bar(T*) 定义中的不同命名空间 [-fpermissive] 中的 '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 {}块中,而第一个定义非常愉快地使用限定名称定义?这只是语言设计的疏忽还是有原因?

4

1 回答 1

14

这里的问题不是定义,而是声明。您不能从不同的命名空间中将声明注入到命名空间中,因此必须在适当的命名空间中声明特化,然后才能在任何封闭的命名空间中对其进行定义。

基础模板的定义可以在外层命名空间中进行,因为它已经被声明了,所以外层命名空间中的代码提供了一个定义,但是并没有将任何声明注入到命名空间中。

尝试:

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;
}
于 2013-08-18T02:57:37.013 回答