以下代码仅在我将-stdlib=libc++
指定为clang++
时才编译:
namespace std {
class mutex;
}
void f(std::mutex &x);
#include <mutex>
void f(std::mutex &x) { }
注意:通过名称查找找到的候选人是&#39; std :: __ 1 :: mutex&#39;
我了解::__1
那里是什么,
但是在我看来,libc++
打破了C ++标准定义的API:
应可以转发声明std::mutex
,因为它应该直接位于std
下,不应该吗?
请注意,编译阶段而非链接阶段失败。所以我不认为我的问题的答案应该是&#34;因为libc ++使用了与GNU libstdc ++不同的ABI ......&#34;
答案 0 :(得分:6)
但在我看来,libc ++打破了C ++标准定义的API:
实际上,它没有。该标准在[contents]中指定:
未指定是否在特定的地方声明了名称 命名空间直接在该命名空间或该命名空间内的内联命名空间中声明。
允许libc ++将mutex
放入inline namespace __1
。请注意,有good reasons需要内联命名空间,通常作为用户,您甚至不关心它们是否存在。
对于您的具体问题,您可以仍然使用libc ++转发声明std::mutex
...您只需要包含所有命名空间(有关如何检测,请参阅this question -std =的libc ++):
namespace std {
#ifdef _LIBCPP_VERSION
inline namespace __1 {
struct mutex;
}
#else
struct mutex;
#endif
}
但是,来自[namespace.std]:
如果C ++程序向名称空间std或a添加声明或定义,则它的行为是未定义的 命名空间std中的命名空间,除非另有说明。
前向声明仍然是一个声明,所以即使上面的内联命名空间占用的版本也是未定义的行为。所以更喜欢直接这样做:
#include <mutex>