在C ++中,应将类模板的显式专门化的定义放在哪里? [英] Where should the definition of an explicit specialization of a class template be placed in C++?

查看:86
本文介绍了在C ++中,应将类模板的显式专门化的定义放在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 [temp.spec]/5 :

对于给定的模板和给定的模板参数集,

  • ...

  • 在程序中最多只能定义一个显式专业化(根据 [ basic.def.odr]/12 (在下面的方框中引用)不包含类模板的完全专业化.而是包含未指定某些模板参数的模板专门化 ".

    一个类类型,枚举类型,具有外部链接的内联函数可以有多个定义( [dcl.inline] ),具有外部链接的内联变量( [temp.concept] ),类模板的静态数据成员,类模板的成员函数或未指定某些模板参数的模板专门化(

    然后会发生错误(由gcc测试),因为S<int>是不完整的类型. /p>

    最后,我应该在哪里放置类模板的显式专业化的定义?

    解决方案

    在这里,我将尝试总结从在我的另一个答案中进行讨论,希望对此问题留下一个好的答案,而不是将答案埋在评论中.

    标准说

    在程序中(根据ODR)最多应定义一次明确的专业化

    ODR是一个定义规则.您只能在一个程序中定义每个类一次,但允许在每个翻译单元中使用一个类定义的例外情况除外:您可以在不同的翻译单元中定义一个类,只要这些不同的定义是相同的,一个字符接一个字符. OP的引用是ODR描述的一部分,请按照 OP的链接查看完整说明.

    因此,IMO上面的标准文字表示,只能根据一次ODR定义一次显式专业化,因此有相同的例外:您可以在头文件中对其进行定义,以便可以在多个转换单元中使用它.

    请注意,没有完整的定义就无法实例化一个类(编译器至少需要知道为其分配多少字节).对于模板化类或此类的特殊化也是如此.因此,定义必须必须存在于使用该定义的每个翻译单元中.

    According to [temp.spec]/5:

    For a given template and a given set of template-arguments,

    • ...

    • an explicit specialization shall be defined at most once in a program (according to [basic.def.odr]), and

    • ...

    the definition of an explicit (full) specialization of a class template cannot be placed in a header (otherwise there is one definition in each translation unit containing this header, thus there will be more than one definition in the whole program).

    In addition, as another evidence, the entities listed in [basic.def.odr]/12 (blockquoted below) do not contain a full specialization of a class template. Instead, "template specialization for which some template parameters are not specified" is contained.

    There can be more than one definition of a class type, enumeration type, inline function with external linkage ([dcl.inline]), inline variable with external linkage ([dcl.inline]), class template, non-static function template, concept ([temp.concept]), static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified ([temp.spec], [temp.class.spec]) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.

    However, if I place the definition in a source file and leave its declaration in a header, for example,

    // "a.h"
    template <typename T>
    struct S {};
    
    template <>
    struct S<int>; // declaration
    
    // "a.cpp"
    #include "a.h"
    
    template <>
    struct S<int> {}; // definition
    
    // "main.cpp"
    #include "a.h"
    
    int main()
    {
        S<int> s;
    }
    

    then an error occurs (tested by gcc) because S<int> is an incomplete type.

    In conclusion, where should I place the definition of an explicit specialization of a class template?

    解决方案

    I am going to try to summarize here what I've learned through the discussion in my other answer, in the hopes of leaving a good answer to this question, rather than having the answer be buried in the comments.

    The standard says

    an explicit specialization shall be defined at most once in a program (according to ODR)

    ODR is the One Definition Rule. You can only define each class once within a program, with an exception designed to allow a class definition to be available in each translation unit: you can define a class in different translation units as long as these different definitions are identical, character for character. The quote of the OP is part of the ODR description, follow the OP's link to see the full description.

    So IMO the standard's text above means that an explicit specialization can be defined only once, but according to the ODR, and thus with the same exceptions: you can define it in a header file so it is available in multiple translation units.

    Note that it is not possible to instantiate a class without its full definition (the compiler needs to know at least how many bytes to allocate for it). The same is true for a templated class, or a specialization of such a class. So it must be possible for the definition to be present in each translation unit that uses it.

    这篇关于在C ++中,应将类模板的显式专门化的定义放在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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