代码之家  ›  专栏  ›  技术社区  ›  oliver

C++功能模板特化的可见性

  •  25
  • oliver  · 技术社区  · 16 年前

    假设我有 fileA.h classA 带模板功能 SomeFunc<T>() SomeFunc() (喜欢 SomeFunc<int>() fileA.C (即不在头文件中)。

    如果我现在打电话 SomeFunc<int>() 从其他代码(可能也来自另一个库),它会调用泛型版本还是专门化?

    9 回复  |  直到 16 年前
        1
  •  22
  •   Anthony Williams    11 年前

    错误

    extern template<> SomeFunc<int>();
    

    这明确声明特定的专门化在其他地方定义。许多编译器已经支持这一点,有些编译器使用 extern .

        2
  •  9
  •   Serge    16 年前

    你在头文件中添加了一个带参数的原型吗?

    我是说文件里有什么

    template<> SomeFunc<int>();
    

    如果不是,那可能就是原因。

        3
  •  3
  •   Aaron Aaron    16 年前

    我在gcc4上遇到了同样的问题,下面是我如何解决它的。这是一个更简单的解决方案,而不是我之前的评论让我相信的。前几篇文章的想法是正确的,但他们的语法对我来说不适用。

    
        ----------header-----------------
        template < class A >
        void foobar(A& object)
        {
          std::cout << object;
        }
    
        template <> 
        void foobar(int);
    
        ---------source------------------
        #include "header.hpp"
    
        template <>
        void foobar(int x)
        {
          std::cout << "an int";
        }
    
    
        4
  •  2
  •   Konrad Rudolph    16 年前

    根据规范,您的专用函数模板不应在外部调用 fileA.C ,除非你 export

    另一方面,一旦函数模板被实例化,编译器就可以看到一个不再是模板的函数。GCC可以跨不同的编译器单元重用这个定义,因为标准规定每个模板对于一组给定的类型参数只能实例化一次[温度规格]. 不过,由于模板没有导出,因此应该仅限于编译单元。

    我相信GCC在跨编译单元共享实例化模板列表时可能会暴露一个bug。通常,这是一个合理的优化,但它应该考虑到函数的特殊化,而这似乎并不能正确地执行。

        5
  •  1
  •   Mark Ransom    16 年前

    两种情况都没有任何警告。我有点怀疑,这就是我做实验的原因。

        6
  •  1
  •   CarLuva    11 年前

    正如安东尼·威廉姆斯所说 extern template 构造是正确的方法,但是由于他的示例代码不完整并且有多个语法错误,这里有一个完整的解决方案。

    文件A.h:

    namespace myNamespace {
      class classA {
        public:
          template <class T> void SomeFunc() { ... }
      };
    
      // The following line declares the specialization SomeFunc<int>().
      template <> void classA::SomeFunc<int>();
    
      // The following line externalizes the instantiation of the previously
      // declared specialization SomeFunc<int>(). If the preceding line is omitted,
      // the following line PREVENTS the specialization of SomeFunc<int>();
      // SomeFunc<int>() will not be usable unless it is manually instantiated
      // separately). When the preceding line is included, all the compilers I
      // tested this on, including gcc, behave exactly the same (throwing a link
      // error if the specialization of SomeFunc<int>() is not instantiated
      // separately), regardless of whether or not the following line is included;
      // however, my understanding is that nothing in the standard requires that
      // behavior if the following line is NOT included.
      extern template void classA::SomeFunc<int>();
    }
    

    文件A.C:

    #include "fileA.h"
    
    template <> void myNamespace::classA::SomeFunc<int>() { ... }
    
        7
  •  0
  •   oliver    16 年前

    我主要在这里寻求启示:-)因为第一个应用程序是一个单元测试,不幸的是有一个bug没有出现在测试中,而是出现在真实的应用程序中。。。

    (注:我已经修复了这个特定的bug,实际上是通过在头中声明了专门化;但是还有哪些类似的bug可能仍然隐藏?)

        8
  •  0
  •   Konrad Rudolph    16 年前

    你确定你没有困惑吗 extern extern template 实例化?从我看来, 外部模板 可以 用于显式实例化,而不是专门化(这意味着隐式实例化)。[温度说明规范]没有提到 关键字:

    显性专业化 :
    template 宣言

        9
  •  0
  •   greatwolf Romowski    12 年前

    除非头文件中也列出了专用模板函数,否则其他应用程序将不知道专用版本。解决方案是添加 SomeFunc<int>()

    推荐文章