相关疑难解决方法(0)

如何使用库中的C++ 11中的'extern'将定义与类模板的声明分开(dll,so,..)

我是开源库的开发人员.我们的一个类是模仿一堆不同的类型.目前,该定义位于头文件中,这会对编译时间产生负面影响,并且还会强制用户包含多于所需的标头.我的目标是:

  • 为了减少编译时间,我想使用C++ 11引入的显式实例化声明.

  • 类方法和成员的定义都是静态的,必须与实现文件中的声明分开.它们应该可以在库外部和内部使用,而无需用户进行显式实例化定义或类似的任何操作.

  • 这必须在支持C++ 11的所有常见编译器上运行跨平台(Visual Studio 2013 +,GCC等)

C++ 11为类模板提供了新功能,特别是" 显式实例化声明 ".据我所知,这可以在这种情况下使用.以前的问题在类似的上下文中处理了这个问题,例如如何使用extern模板和分离模板类的定义/实例化而没有'extern'但是那些不处理库导出,如果客户端尝试使用共享库,它们的解决方案会导致链接器错误.

目前我已经设法以在Visual Studio 2015上编译,链接和运行的方式实现它,但我不确定我是否正确使用了关键字,尤其是在这种情况下的__declspec.这就是我得到的(简化):

// class.h
template<typename T>
class PropertyHelper;

template<typename T>
class PropertyHelper<const T>
{
public:
    typedef typename PropertyHelper<T>::return_type return_type;

    static inline return_type fromString(const String& str)
    {
        return PropertyHelper<T>::fromString(str);
    }

    static const int SomeValue;
};


template<>
class EXPORTDEF PropertyHelper<float>
{
public:
    typedef float return_type;

    static return_type fromString(const String& str);

    static const int SomeValue;
};

extern template EXPORTDEF class PropertyHelper<float>;
Run Code Online (Sandbox Code Playgroud)

最后一行是显式实例化声明.据我所知,这意味着客户不必每次都自己申报.EXPORTDEF是Windows上的__declspec(dllexport)或__declspec(dllimport)的定义.我不确定是否需要将其放在上面的行中,因为以下内容还编译,链接和运行:

extern …
Run Code Online (Sandbox Code Playgroud)

c++ dll templates c++11

20
推荐指数
1
解决办法
3526
查看次数

VS 2012中的显式模板声明/定义

以下代码声明了一个模板,声明了一个显式的实例化定义,然后声明了一个显式的实例化声明:

template <typename T>
T Double(T number)
{
    return number * 2;
}

extern template int Double<int>(int);  // declaration
template int Double<int>(int t);       // definition

int main(int argc, char* argv[])
{
    int n = Double(10);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

给出错误:

error C2929: 'int Double<int>(int)' : explicit instantiation; cannot explicitly force and suppress instantiation of template-class member
Run Code Online (Sandbox Code Playgroud)

在Visual Studio 2012中.

我的印象来自http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm,这应该是有效的,因为定义遵循声明.

我错过了什么吗?

c++ templates c++11 visual-studio-2012

8
推荐指数
1
解决办法
1025
查看次数

标签 统计

c++ ×2

c++11 ×2

templates ×2

dll ×1

visual-studio-2012 ×1