The following program, when compiled with either GCC 4.7 and clang 3.2, produces “1” as output.
#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>();
}
This is confusing. foo is quite clearly not constructible from int! If I change main to the following, both compilers reject it due to the static assertion failing:
int main() {
foo(0);
}
How come both compilers say it is constructible?
This is what the standard has to say (§20.9.5/6), with my emphasis:
The assertion only fails when the template constructor is instantiated. However, as cleared up in the note, that assertion is not in the immediate context of the variable definition that is considered, and thus does not affect its “validity”. So the compilers can count that definition as valid, and thus claim that
foois indeed constructible fromint, even if actually attempting to construct afoofrom anintresults in an ill-formed program.Note that the compilers are also allowed to, instead of having
is_constructibleyield false, just reject the original program based on the assertion, even though neither one does.