向前声明类模板的显式/部分专业化有什么意义? [英] What's the point of forward declaring a class template explicit/partial specialization?

查看:124
本文介绍了向前声明类模板的显式/部分专业化有什么意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 98标准说:

The C++98 standard says:

[temp.class.spec]部分专业化声明本身无法通过名称查找找到.

[temp.class.spec] Partial specialization declarations themselves are not found by name lookup.

如果对于显式专业化也是如此,则这使得对类模板的显式/部分专业化的前向声明不可见.

If this is also true for explicit specializations, this makes a forward-declaration of a class template explicit/partial specialization invisible.

[temp.class.spec.match]在需要实例化类的上下文中使用类模板时,有必要确定是使用主模板还是部分模板中的一个来生成实例化专业化.

[temp.class.spec.match] When a class template is used in a context that requires an instantiation of the class, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations.

这意味着直到匹配的专业化的(隐式)实例化点时才进行显式/部分专业化的选择-仅在需要完全定义该类时才会发生.

This implies that the choice of explicit/partial specialization is not made until the point of (implicit) instantiation of a matching specialization - which only occurs when the class is required to be completely defined.

在下面的示例中,向前声明的显式专业化的唯一作用是使程序无法编译.

In the following example, the only effect the forward-declared explicit-specializations have is to make the program fail to compile.

namespace N
{
    template<class T>
    struct S
    {
    };

    typedef S<char> Type; // name lookup finds S<T>

    template<>
    struct S<char>; // invisible to name lookup

    typedef S<char> Type; // name lookup finds S<T>

    int f(S<char>*); // name lookup finds S<T>

    S<int> object; // implicitly instantiates S<int>

    template<>
    struct S<int>; // illegal, explicit specialization after instantiation
}

N::S<char>* p = 0; // name lookup finds N::S<T>
int i = f(p); // name lookup finds N::f via ADL


N::S<char> object; // illegal, incomplete type N::S<char>

在这两种情况下,使程序编译的唯一方法(除了删除专业化对象)是在实例化两个专业化对象之前提供一个定义-这使得前向声明有点毫无意义.

In both cases, the only way to make the program compile (apart from deleting the specializations) is to provide a definition for both specializations before they are instantiated - which makes the forward-declaration a bit pointless.

此行为是否有任何实际的实际应用?除此之外,这些前向声明还有什么用吗?

Does this behaviour have any practical real-world application? Apart from this, is there anything these forward-declarations are useful for?

推荐答案

并不是唯一的目的就是使程序无法编译.下面,V2是格式错误;不需要诊断",而V1格式正确.

It is not true that the only purpose is to make the program fail to compile. In the following, V2 is "ill-formed; no diagnostic required", while V1 is well-formed.

namespace N {
   template<typename T> struct A {
      friend void f(A *a) { } // would take this with V2
   };
}
void f(void*) { } // would take this with V1

namespace N {
/* V1: */ template<> struct A<int>;
}

int main() {
   N::A<int> *p;
   f(p);
}

namespace N {
/* V2: */ template<> struct A<int>;
}

这篇关于向前声明类模板的显式/部分专业化有什么意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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