为什么is_constructible声称某物是可构造的,而实际上并非如此?
Why does is_constructible claim something is constructible when it isn't?
以下程序在使用GCC 4.7和clang 3.2编译时,产生"1"作为输出。
#include <type_traits>
struct foo {
template<typename T>
foo(T) {
static_assert(not std::is_same<int, T>(), "no ints please");
}
};
#include <iostream>
int main() {
std::cout << std::is_constructible<foo, int>();
}
这是令人困惑的。 foo
显然无法从int
中构建!如果我将main
更改为以下内容,则由于静态断言失败,两个编译器都拒绝它:
int main() {
foo(0);
}
为什么两个编译器都说它是可构造的?
这就是标准(§20.9.5/6(的内容,我强调:
给定以下函数原型:
template <class T> typename add_rvalue_reference<T>::type create();
模板专用化的谓词条件
is_constructible<T, Args...>
当且仅当 以下变量定义对于某些发明的格式很好 可变t
:T t(create<Args>()...);
[ 注意:这些标记永远不会被解释为函数 声明。—尾注 ]
访问检查的执行就像在与
T
和 任何Args
.只有直接上下文的有效性 考虑变量初始化。[注:评价 初始化可能会导致副作用,例如实例化 类模板专用化和函数模板专用化, 生成隐式定义的函数,等等。这样的一面 效果不在"直接上下文"中,可能导致 程序格式不正确。—尾注 ]
仅当实例化模板构造函数时,断言才会失败。然而,正如说明中所澄清的,这种断言不在所考虑的变量定义的直接上下文中,因此不影响其"有效性"。因此编译器可以将该定义视为有效,从而声称foo
确实可以从int
构造,即使实际上试图从int
构造一个foo
会导致程序格式错误。
请注意,编译器也允许编译器根据断言拒绝原始程序,而不是is_constructible
产生假,即使两者都没有。
foo2
是你的foo
。 foo1
是一个 foo 可以做您希望您的foo
做的事情。
#include <type_traits>
#include <utility>
struct foo1 {
template<typename T,typename=typename std::enable_if< !std::is_same<int, T>::value >::type>
foo1(T) {
static_assert(not std::is_same<int, T>(), "no ints please");
}
};
struct foo2 {
template<typename T>
foo2(T) {
static_assert(not std::is_same<int, T>(), "no ints please");
}
};
#include <iostream>
int main() {
std::cout << std::is_constructible<foo1, int>();
std::cout << std::is_constructible<foo2, int>();
}
相关文章:
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么我的删除节点函数实际上没有删除节点?
- 其中降频广播实际上是有用的
- "delete"在 C++ 中实际上做了什么?
- C++:实际上不是从二进制文件中读取
- 在这里,当我们比较 if(vc[i]==vc1[i]) 时,它是向量数组. 实际上比较的值是多少,
- 您好,我实际上想了解以下代码.有人可以详细说明代码它到底在做什么吗?为什么它会在第 31 行崩溃
- 为什么我们实际上需要运行时多态性?
- FlatBuffers C++ reinterpret_cast访问实际上是未定义的行为吗?这样做实际上可以吗?
- 特征实际上扩展了稀疏矩阵
- *(int*)&data[18]在这段代码中实际上做了什么?
- C ++相同的字符串不相等(实际上是char*)
- 成员函数的"this"参数具有"const"类型,但我的函数实际上不是"const"
- 使用带有 std::cout 的单引号打印字符串实际上打印了数字
- 为什么编译器无法弄清楚构造函数实际上是 constexpr?
- 实际上,C++11 中 std::atomic 的内存占用量是多少?
- SQLHANDLE-Parameters:函数不接受x个参数(但实际上确实如此)
- Cppcheck 静态代码分析器实际上可以检测到不太常见的警告(如 "Relative Path Traversal (CWE-23)" 或"Buffer Under-read(CWE-127)")吗
- 转化会失去限定符,但实际上并非如此
- 为什么is_constructible声称某物是可构造的,而实际上并非如此?