gpt4 book ai didi

c++ - std::is_constructible::value 的正确结果是什么?

转载 作者:可可西里 更新时间:2023-11-01 16:38:42 27 4
gpt4 key购买 nike

std::is_constructible<void()>::value 的结果不一致.我对该标准的解释是它应该是错误的。然而,Clang,同时具有 libc++ 和 libstdc++*,给出了 true。 GCC 和 MSVC 都给出 false。哪个结果是正确的?

标准语

这是标准的 N4527 [meta.unary.prop]/7:

Given the following function declaration:

template <class T> add_rvalue_reference_t<T> create() noexcept;

the predicate condition for a template specialization is_constructible<T, Args...> shall be satisfied if and only if the following variable definition would be well-formed for some invented variable 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()>();
}

结果:

Clang (HEAD, libc++) :

  • 静态断言通过
  • foo<void()>没有编译

Clang (HEAD, libstdc++) *:

  • 静态断言通过
  • foo<void()>没有编译

GCC (HEAD, libstdc++) :

  • 静态断言失败
  • foo<void()>没有编译

MSVC(版本 19 通过 http://webcompiler.cloudapp.net/ ):

  • 静态断言失败
  • foo<void()>没有编译(需要注释掉静态断言)

* __GLIBCXX__当 Clang 与 no -stdlib 一起使用时未定义选项和 -stdlib=libstdc++ .我不确定 libstdc++ 是否实际上正在被使用。如果我对标准的解释是正确的,那么我不确定它是 Clang 还是 libc++ 的错误。

最佳答案

继续阅读。来自同一段:

Access checking is performed as if in a context unrelated to T and any of the Args. Only the validity of the immediate context of the variable initialization is considered. [ Note: The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context” and can result in the program being ill-formed. —end note ]

断言仅在实例化模板构造函数时失败。但是,正如注释中所阐明的那样,该断言不在所考虑的变量定义的直接上下文中,因此不会影响其“有效性”。因此编译器可以将该定义视为有效,即使实际尝试构建 void() 会导致程序格式错误。

请注意,编译器也可以根据断言拒绝原始程序,而不是让 is_constructible yield false。

关于c++ - std::is_constructible<void()>::value 的正确结果是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33058915/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com