c++ - 使用(和导出)boost::shared_ptr<T> 时出现错误 C2562

标签 c++ windows visual-studio boost dll

各位程序员好,

我正在创建一个 C++ DLL 库,我在其中使用了 boost (1.55) 的 shared_ptr。 然而,当我使用 Visual Studio 2013 编译项目时,出现了一堆错误 C2562:

Error   1   error C2562: 'boost::shared_ptr<MEngine::i18n::ITranslationSource>::operator []' : 'void' function returning a value    f:\developer\cplus\lib\boost_1_55_0\boost\smart_ptr\shared_ptr.hpp  663 1   MEngine
Error   2   error C2562: 'boost::shared_ptr<MEngine::i18n::ITranslationSource>::operator []' : 'void' function returning a value    f:\developer\cplus\lib\boost_1_55_0\boost\smart_ptr\shared_ptr.hpp  663 1   MEngine
Error   3   error C2562: 'boost::shared_ptr<MEngine::Object::GameObject>::operator []' : 'void' function returning a value  f:\developer\cplus\lib\boost_1_55_0\boost\smart_ptr\shared_ptr.hpp  663 1   MEngine
Error   4   error C2562: 'boost::shared_ptr<MEngine::Object::GameObject>::operator []' : 'void' function returning a value  f:\developer\cplus\lib\boost_1_55_0\boost\smart_ptr\shared_ptr.hpp  663 1   MEngine
Error   5   error C2562: 'boost::shared_ptr<MEngine::Object::GameObject>::operator []' : 'void' function returning a value  f:\developer\cplus\lib\boost_1_55_0\boost\smart_ptr\shared_ptr.hpp  663 1   MEngine
Error   6   error C2562: 'boost::shared_ptr<MEngine::i18n::ITranslationSource>::operator []' : 'void' function returning a value    f:\developer\cplus\lib\boost_1_55_0\boost\smart_ptr\shared_ptr.hpp  663 1   MEngine
Error   7   error C2562: 'boost::shared_ptr<MEngine::i18n::ITranslationSource>::operator []' : 'void' function returning a value    f:\developer\cplus\lib\boost_1_55_0\boost\smart_ptr\shared_ptr.hpp  663 1   MEngine
Error   8   error C2562: 'boost::shared_ptr<MEngine::i18n::ITranslationSource>::operator []' : 'void' function returning a value    f:\developer\cplus\lib\boost_1_55_0\boost\smart_ptr\shared_ptr.hpp  663 1   MEngine

如您所见,每个 shared_ptr 模板实例化都有相同的错误。 问题是我从不使用该运算符,所以不应该生成它的代码吗?

在那种情况下,出现该错误的原因是完全可以理解的,因为在 shared_ptr.h 中有:

typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
{
    BOOST_ASSERT( px != 0 );
    BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );

    return px[ i ];
}

还有:

template< class T > struct sp_array_access
{
    typedef void type;
};
...
template< class T > struct sp_array_access< T[] >
{
    typedef T & type;
};
...

这意味着对于 smart_ptr< T > 如果 T 不是数组,则 operator[] 的返回类型为 void,因此运算符的代码将无法编译。

所以真正的问题是(我认为)运算符的代码已生成,但它不应该生成。 我需要将 shared_ptr 导出到我的 DLL 接口(interface),因为它是一个模板,所以我使用它来实例化和导出它:

EXPIMP_TEMPLATE template class MENGINE_API boost::shared_ptr<MEngine::i18n::ITranslationSource>;

宏在哪里(非常标准):

#ifdef MENGINE_EXPORTS
#define MENGINE_API _declspec(dllexport)
#define EXPIMP_TEMPLATE
#else
#define MENGINE_API _declspec(dllimport)
#define EXPIMP_TEMPLATE extern
#endif

我正在使用的导出语句是否会导致生成模板中的所有内容? 如果这是真的,那么我该如何克服并实现导出?

为我的英语道歉:) 纠正我也非常感谢,因为我愿意学习:)

最佳答案

C++11 14.7.2 [temp.explicit] 第 8 段:

An explicit instantiation that names a class template specialization is also an explicit instantiation of the same kind (declaration or definition) of each of its members (not including members inherited from base classes) that has not been previously explicitly specialized in the translation unit containing the explicit instantiation, except as described below.

在不支持“如下所述”的所有细节的情况下,您的显式实例化实例化了所有定义明确或不明确的成员。这就是显式实例化的要点:将每个成员的所有代码都定义在一个地方。在实例化时,不清楚是否会实际使用哪个成员:据您所知,某些链接到您的库的客户端可能会使用该 operator[]

理想的解决方法是(此处随意猜测)使用 std::enable_if 移除非数组类型的 operator[] 重载,而不是让代码出错- 为非数组类型形成。

一些其他选项:

  • 不要显式实例化任何东西。
  • 单独显式实例化每个所需的成员,避免格式错误的成员。

关于c++ - 使用(和导出)boost::shared_ptr<T> 时出现错误 C2562,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20816943/

相关文章:

visual-studio - 如何为可视代码 GO 插件省略 GOPATH

c# - 如何忽略 NodaTime nuget 包 xml 文档文件中对 jetbrains.annotations.dll 的引用

c++ - std::make_shared 与 std::initializer_list

windows - 基于 Windows 7 上的 Perl

c# - .Net 内存增长问题

c++ - 相当于 Linux 中的导入库

visual-studio - 在 Visual Studio 2015 中打开网站时出现空白安全警告

c++ - move 语义以避免创建临时对象

c++ - QList::at() 返回对常量的引用?

c++ - 关于仅 header C++ 库使用的可量化指标(基准)