当切换到C++11时,是否需要重新编译所有使用STL接口的依赖库?

7
我尝试将一个大型项目转换为使用C++11。我遇到了许多链接器错误,这些错误似乎是由于使用C++11编译的库与使用C++03编译的库之间的STL类命名空间不匹配造成的。
例如,假设库B是A的依赖项。B具有以下模板类作为其接口的一部分。
template <class Type>
class VectorParameter
{
public:
    VectorParameter();
    virtual ~VectorParameter();

    ...
}

Library A使用VectorParameter<std::pair<float, float>>实例化模板。

当我重新使用C++11编译A而没有重新编译B时,我遇到了链接错误,报告如下:

LFE::VectorParameter<std::__1::pair<float, float>>::~VectorParameter()是未定义的符号。

我认为问题在于库A使用了std::__1::pair而B仍然使用std::pair。根据这个推理,我假设需要重新编译所有依赖库,以便它们在接口中引用STL类型。

如果是这样,那么将一个大型项目迁移到C++11将需要所有相关组同时切换,这在复杂的项目中似乎不太实际。如何处理这个问题才是最佳实践呢?


3
我宁愿安全无事,即重新编译整个程序。这是一个一次性的事件。 - Ed Heal
2
很可能,C++03和C++11之间的标准库ABI将是不同的。如果没有在所有相关依赖项上打开C++11开关,我甚至都不会尝试这样做。 - Praetorian
2
一般来说,所有的库都必须使用非常相似甚至相同的标志进行编译。而C++11则是一个比较重要的标志... - Mooing Duck
3
可能是重复的问题:https://dev59.com/Bmkw5IYBdhLWcg3wQ4dc - sbabbi
1
你应该重建所有依赖于STL的东西。但是,鉴于您发布的代码,我想知道您是否将模板声明放在头文件中,将定义放在实现文件中。这也会导致“未定义的符号”错误;修复方法是将声明/定义都放在头文件中或使用extern模板(C++11功能:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm)。 - Max Lybbert
显示剩余2条评论
2个回答

9
几乎可以确定库头文件已更改,因此为了符合一次定义规则,您必须重新编译所有内容。

4
您没有指定您的平台或编译器/库。
这里有一些有趣的注释(尽管有点过时),关于GNU libStdc++的ABI兼容性 - 这是一些对真正遵守标准的代价。如果使用std::pair,似乎要么全部遵循,要么完全不遵循。 libc ++(即clang的标准库)采用另一种方法,故意向其所有导出符号插入额外的名称空间(我认为称为__1),这意味着可能将libstdc ++libc ++链接到同一个可执行文件中。只要在旧库和新库之间没有传递STL对象,您可能会成功地使其工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接