c – 使用(和导出)boost :: shared_ptr时出现错误C2562

嗨其他程序员,

我正在创建一个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接口,因为它是一个模板,我用它来实例化并导出它:

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.

如果不支持“下面描述的”所有细节,那么您的显式实例化将实例化所有明确定义的成员或其他成员.这是显式实例化的要点:在一个地方定义每个成员的所有代码.在即时的时候,还不清楚哪些成员实际上会被使用:你所知道的,一些链接到你的库的客户端可能会使用该运算符[].

理想的解决方法是(在这里疯狂推测)使用std :: enable_if来移除非数组类型的operator []重载,而不是使代码格式化为非数组类型.

其他一些选择:

>不要明确地实例化任何东西.
>单独显式地实例化每个所需成员,避免形成不良成员.

点赞