Does
std::is_constructible<T, Arg1>
Arg1
T
static_assert
#include <type_traits>
struct foo
{
foo(int) {}
foo(int, int) {}
};
struct converts
{
template <class T>
operator T(){}
};
int main()
{
// These compile
foo f1(converts());
foo f2(converts(), converts());
static_assert(std::is_constructible<foo, converts, converts>::value, "foo(converts(), converts())");
// This line doesn't
static_assert(std::is_constructible<foo, converts>::value, "foo(converts())");
}
This is just a Most Vexing Parse issue. Since the line foo f1(converts())
can be seen as a declaration of a function f1
, the compiler must treat it as a declaration. If you switch the parentheses for braces, the first line stops compiling:
int main()
{
foo f1{converts()}; // Now broken
foo f2{converts(), converts()};
}
The error message helpfully tells us that the compiler can't determine whether to call foo(int)
, or foo(const foo&)
, or foo(foo&&)
, as converts
could also be converted into foo
with its templated conversion operator.
When you use the parentheses, we can see by using decltype
that the compiler sees f1
as a declaration of a function of type foo(converts(*)())
– a function returning foo
, which takes one argument which is a function pointer.