[英]What is the portable way to forward-declare classes in an inline namespace in libc++?
仅当我将-stdlib=libc++
指定为clang++
时,以下代码才会编译:
namespace std {
class mutex;
}
void f(std::mutex &x);
#include <mutex>
void f(std::mutex &x) { }
注意:通过名称查找找到的候选人是'std :: __ 1 :: mutex'
我明白什么是::__1
那里,
但在我看来, libc++
打破了C ++标准定义的API:
应该可以转发声明std::mutex
因为它应该直接驻留在std
下,不应该吗?
请注意,编译阶段而不是链接阶段失败。 所以我认为我的问题的答案应该是“因为libc ++使用了与GNU libstdc ++不同的ABI ......”
但在我看来,libc ++打破了C ++标准定义的API:
实际上,它没有。 该标准在[contents]中指定:
未指定在特定名称空间中声明的名称是直接在该名称空间中声明还是在该名称空间内的内联名称空间中声明。
libc ++允许将mutex
放在inline namespace __1
。 请注意,有充分的理由需要内联命名空间,通常作为用户,您甚至不关心它们是否存在。
对于您的具体问题,您仍然可以使用libc ++转发std::mutex
...您只需要包含所有命名空间(请参阅此问题以了解如何检测-std = libc ++):
namespace std {
#ifdef _LIBCPP_VERSION
inline namespace __1 {
struct mutex;
}
#else
struct mutex;
#endif
}
但是,从[namespace.std]:
如果C ++程序向命名空间std或命名空间std中的命名空间添加声明或定义,则它是未定义的,除非另有说明。
前向声明仍然是一个声明,因此即使上面的内联命名空间占用的版本也是未定义的行为。 所以更喜欢直接这样做:
#include <mutex>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.