【发布时间】:2015-10-10 20:57:49
【问题描述】:
std::is_constructible<void()>::value 的结果不一致。我对标准的解释是它应该是错误的。但是,具有 libc++ 和 libstdc++* 的 Clang 给出了 true。 GCC 和 MSVC 都给出错误。哪个结果是正确的?
标准
这里是标准的,N4527 [meta.unary.prop]/7:
给定以下函数声明:
template <class T> add_rvalue_reference_t<T> create() noexcept;模板特化的谓词条件 当且仅当满足
is_constructible<T, Args...>对于某些发明,以下变量定义将是格式良好的 变量t:T t(create<Args>()...);
注意:此文本与 C++11 (N3485) 略有不同,其中 create 未标记为 noexcept。但是,考虑到这一点,我的测试结果并没有改变。
测试用例
这是我对类型特征和标准定义的最小测试用例:
#include <type_traits>
static_assert(std::is_constructible<void()>::value, "assertion fired");
template<typename T>
std::add_rvalue_reference_t<T> create() noexcept;
template<typename T, typename... Args>
void foo() {
T t(create<Args>()...);
}
int main() {
foo<void()>();
}
结果:
- 静态断言通过
-
foo<void()>没有编译
- 静态断言通过
-
foo<void()>没有编译
- 静态断言失败
-
foo<void()>没有编译
MSVC(版本 19,通过 http://webcompiler.cloudapp.net/):
- 静态断言失败
-
foo<void()>没有编译(需要注释掉静态断言)
*__GLIBCXX__ 没有在没有-stdlib 选项和-stdlib=libstdc++ 的情况下使用 Clang 时没有定义。我不确定是否实际上正在使用 libstdc++。如果我对标准的解释是正确的,那么我不确定它是 Clang 还是 libc++ 的错误。
【问题讨论】:
-
@T.C.,谢谢!很酷。
标签: c++ language-lawyer typetraits