使用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节),我强调:
断言仅在实例化模板构造函数时失败。但是,正如注释中所阐明的那样,断言不是在所考虑的变量定义的直接上下文中,因此不会影响其“有效性”。因此,编译器可以将该定义视为有效,因此声称foo
确实可以从int
构造,即使实际上尝试从foo
构造int
也会导致程序格式错误。
请注意,即使没有人这样做,也允许编译器拒绝基于assertion的原始程序,而不是让is_constructible
产生false。