为什么可以模板< T>但不是模板<>在命名空间块之外定义? [英] Why can template<T> but not template<> be defined outside of a namespace block?

查看:224
本文介绍了为什么可以模板< T>但不是模板<>在命名空间块之外定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是一些无法编译的代码。

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

错误是:specialization of'template int ns :: foo ::不同命名空间中的bar(T *)[-fpermissive]与'template int ns :: foo :: bar(T *)'的定义

The error is: "specialisation of ‘template int ns::foo::bar(T*)’ in different namespace [-fpermissive] from definition of ‘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 {} 阻塞,当第一个使用限定名称很高兴地定义?它只是一个在语言设计的监督,或有这样的原因吗?

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?

推荐答案

这里的问题不是定义,但是声明。您无法在命名空间中注入来自不同命名空间的声明,因此必须在适当的命名空间中声明专业化 ,然后才能在任何封闭命名空间中定义

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.

尝试:

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

这篇关于为什么可以模板&lt; T&gt;但不是模板&lt;&gt;在命名空间块之外定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆