What's the point of forward declaring a class template explicit/partial specialization?

﹥>﹥吖頭↗ 提交于 2019-12-12 18:26:53

问题


The C++98 standard says:

[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] 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?


回答1:


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


来源:https://stackoverflow.com/questions/17200312/whats-the-point-of-forward-declaring-a-class-template-explicit-partial-speciali

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!