在 libc++ 的内联命名空间中转发声明 类 的可移植方式是什么?
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) { }
- http://goo.gl/Uqpv6f (gcc.godbolt.org)
note: candidate found by name lookup is 'std::__1::mutex'
我明白::__1
那里是什么,
但在我看来,libc++
打破了 C++ 标准定义的 API:
- http://en.cppreference.com/w/cpp/thread/mutex(好吧,这真的不是一个标准...)
应该 可以转发声明 std::mutex
因为它应该直接位于 std
之下,不是吗?
请注意编译阶段失败,而不是链接阶段失败。所以我认为我的问题的答案不应该是 "because libc++ employs a different ABI from GNU libstdc++..."
but to my eyes, libc++ breaks the API defined by the C++ standard:
其实不然。标准在[内容]中规定:
It is unspecified whether names declared in a specific
namespace are declared directly in that namespace or in an inline namespace inside that namespace.
libc++允许将mutex
放入inline namespace __1
。请注意,有 good reasons 需要内联名称空间,通常作为用户,您甚至不关心它们是否存在。
对于您的具体问题,您可以仍然使用 libc++ 向前声明 std::mutex
...您只需要包括所有名称空间(参见 如何检测 -std=libc++):
namespace std {
#ifdef _LIBCPP_VERSION
inline namespace __1 {
struct mutex;
}
#else
struct mutex;
#endif
}
但是,来自 [namespace.std]:
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a
namespace within namespace std unless otherwise specified.
前向声明仍然是一个声明,因此即使是上述说明内联命名空间的版本也是未定义的行为。所以更喜欢直接的方式:
#include <mutex>
仅当我将 -stdlib=libc++
指定为 clang++
时,以下代码才不会编译:
namespace std {
class mutex;
}
void f(std::mutex &x);
#include <mutex>
void f(std::mutex &x) { }
- http://goo.gl/Uqpv6f (gcc.godbolt.org)
note: candidate found by name lookup is 'std::__1::mutex'
我明白::__1
那里是什么,
但在我看来,libc++
打破了 C++ 标准定义的 API:
- http://en.cppreference.com/w/cpp/thread/mutex(好吧,这真的不是一个标准...)
应该 可以转发声明 std::mutex
因为它应该直接位于 std
之下,不是吗?
请注意编译阶段失败,而不是链接阶段失败。所以我认为我的问题的答案不应该是 "because libc++ employs a different ABI from GNU libstdc++..."
but to my eyes, libc++ breaks the API defined by the C++ standard:
其实不然。标准在[内容]中规定:
It is unspecified whether names declared in a specific namespace are declared directly in that namespace or in an inline namespace inside that namespace.
libc++允许将mutex
放入inline namespace __1
。请注意,有 good reasons 需要内联名称空间,通常作为用户,您甚至不关心它们是否存在。
对于您的具体问题,您可以仍然使用 libc++ 向前声明 std::mutex
...您只需要包括所有名称空间(参见
namespace std {
#ifdef _LIBCPP_VERSION
inline namespace __1 {
struct mutex;
}
#else
struct mutex;
#endif
}
但是,来自 [namespace.std]:
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified.
前向声明仍然是一个声明,因此即使是上述说明内联命名空间的版本也是未定义的行为。所以更喜欢直接的方式:
#include <mutex>