【问题标题】:function template specialization ignored by the compiler编译器忽略的函数模板特化
【发布时间】:2014-01-21 13:47:45
【问题描述】:

我们的项目使用 boost::serialization 来序列化很多东西。 但是有些类型没有正确注册,在序列化它们时我们得到一个“未注册的类”错误 我已将问题缩小到 BOOST_CLASS_EXPORT_KEY,对于某些类型,它不会生成代码。 BOOST_CLASS_EXPORT_KEY 的作用是:

namespace boost {
    namespace serialization {
        template<>
        struct guid_defined< T > : boost::mpl::true_ {};
        template<>
        inline const char * guid< T >(){
            return K;
        }
    } /* serialization */
} /* boost */

所有被序列化的对象都继承自一个名为 Serializable 的基类。 序列化总是通过指向基类的指针来完成的。

这很好用,除了一种情况: 有一个类模板 SerializableList,它是一个 Serializable,它包含一个 T

列表
template< typename T>
class SerializableList
{
    ...
    std::vector<T> m_list;

    template<class Archive>
    void serialize( Archive & ar, const unsigned int /*version*/ )
    {
        ar & boost::serialization::base_object<businessObjects::Serializable>(*this);
        ar & mList;
    }
};

然后,我们在专用的 cpp 和 hpp 文件中声明此模板的每个实例化以促进序列化,如下所示:

hpp:

BOOST_CLASS_EXPORT_KEY( SerializableList<SomeT*> );
BOOST_CLASS_EXPORT_KEY( SerializableList<SomeOtherT*> );
BOOST_CLASS_EXPORT_KEY( SerializableList<AThirdT*> );

cpp:

BOOST_CLASS_EXPORT_IMPLEMENT( SerializableList<SomeT*> );
BOOST_CLASS_EXPORT_IMPLEMENT( SerializableList<SomeOtherT*> );
BOOST_CLASS_EXPORT_IMPLEMENT( SerializableList<AThirdT*> );

但是这些行中有一半不会在最终的可执行文件中生成可执行代码!如果我们在每一行都设置一个断点并运行,一半的断点会消失,留下的那些是工作类型(那些我们可以序列化的)。 例如,断点将保留在 SerializableList&lt;SomeT*&gt;SerializableList&lt;AThirdT*&gt; 而不是 SerializableList&lt;SomeOtherT*&gt;

顺便说一句,我们也尝试过直接调用boost::serialization::guid&lt;T&gt;(),虽然它可以正常工作,但可以说: boost::serialization::guid&lt;SerializableList&lt;SomeT*&gt; &gt;() 返回密钥, 它不适合 boost::serialization::guid&lt;SerializableList&lt;SomeOtherT*&gt; &gt;() 调用默认实现...

那么是否存在编译器错误(我们使用 Visual C++ 2010 SP1),或者编译器是否有充分的理由忽略其中一些特化?

我忘了提,所有这些代码都在一个库中,该库与 exe 项目链接。我尝试过使用不同的 exe 项目,有时它可以工作,有时它不...编译选项是相同的...我真的 不知道发生了什么:'(

【问题讨论】:

  • 您是否尝试显式实例化(缺失)类:template class SerializableList&lt;SomeOtherT*&gt;;
  • "我忘了说,所有这些代码都在一个库中" 这可能是问题所在。它是静态库还是动态库? (我会尝试找到类似的问题,因为 IIRC 这个问题之前已经在 SO 上描述过)
  • boost docs: "在库代码中放置 BOOST_CLASS_EXPORT 将无效,除非还包含归档类头文件。因此,在构建库时,应包含所有归档类的所有头文件他预计会使用它。或者,可以只包含 Polymoprhic 档案的标题。”(另见:stackoverflow.com/q/7875107/420683
  • 另外,您可以尝试/OPT:NOREF(属性->链接器->优化)或导出/导入BOOST_CLASS_EXPORT_IMPLEMENT创建的变量
  • 如果您在评论中添加@usernamethe user will be notified。将自动通知答案/帖子的所有者。 -- 如果幸运的话,您现在可能会发现 SSCCE 和您的实际程序之间存在差异的错误 :)(保持乐观)

标签: c++ templates visual-c++ boost template-specialization


【解决方案1】:

我们找到了解决方案,

一个(可序列化的)类有多个 SerializableList 成员,并且不包括具有所有“BOOST_CLASS_EXPORT_KEY”行的文件。

其他正在运行的项目没有使用那个特定的类...

【讨论】:

    猜你喜欢
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    相关资源
    最近更新 更多