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

问题描述

C ++ 98标准说:

The C++98 standard says:

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

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

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

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

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

08-13 01:41