使用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。

10-04 15:04