【问题标题】:Compile against a outdated explicit instantiation of a template针对模板的过时显式实例化进行编译
【发布时间】:2020-10-13 19:37:22
【问题描述】:

我使用了一个库 (Orocos),它使用自定义分配器定义了自己的 std::basic_string。此外,它显式地实例化它:

命名空间 RTT
{
    typedef std::basic_string, RTT::os::rt_allocator > rt_string;
}

命名空间标准
{
    外部模板类 basic_string, RTT::os::rt_allocator >;
}

在我切换到 C++17 之前,它运行良好。在 C++ 17 中,std::basic_string 具有新功能,即data() 的非 const 版本。现在,当我编译时,我得到了对 RTT::rt_string::data() 的未定义引用,因为 Orocos 不知道 C++17。

最“正确”的做法是什么?

  • 修补库以至少编译 C++17 中的模板实例化。
  • 修补库以不显式实例化此类。
  • 不要使用这些方法。我可以应付,但每次我在非常量对象上使用该方法时,我都必须做类似const_cast<RTT::rt_string const&>(myString).data() 之类的事情。另外,如果我忘记了,我会再次出现奇怪的链接器错误。
  • 以某种方式将这些符号添加到我的库中。
  • data() 是一个隐式内联函数,如果我在发行版中编译,问题应该就消失了。不是真正的解决方案。

【问题讨论】:

  • 即使没有显式实例化,您也应该首先检查用于编译 Orocos 的标准库 abi 是否与您正在使用的兼容。我怀疑答案是否定的。如果您成功链接,执行可能会导致严重的意外。
  • 我们使用相同的编译器 (GCC9) 编译这两个库,所以应该没有 ABI 不兼容或 _GLIBCXX_USE_CXX11_ABI 问题。
  • 你试过用-std=c++17编译Orocos吗?
  • @Oliv 我可以,但我不想尽可能自己编译我的依赖项。

标签: c++ linker c++17


【解决方案1】:

您应该能够将缺少的成员函数的显式实例化定义添加到您自己的代码中(仅在一个源文件中):

template char* std::basic_string<char, std::char_traits<char>, RTT::os::rt_allocator<char> >::data() noexcept;

这并不严格符合标准库中的成员函数签名,但同时使用两种语言版本已经超出标准的正式范围(使用两种不同版本的任何以这种方式定义的类(模板)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 2021-05-02
    相关资源
    最近更新 更多