I'd like to check how and if an object of type A can be constructed from an object of type B.
I also want to distinguished between direct and copy initialization and thus wrote these concepts:
template<typename A, typename B>
concept can_direct_init_from = requires { A{std::declval<B>()}; };
template<typename A, typename B>
concept can_copy_init_from = requires { A a = std::declval<B>(); };
The first one, I think, is strictly equivalent to std::constructible_from
but I don't know of a similar concept for the copy initialization case.
std::convertible_to
does not seem to be used for a copy initialization (according to the corresponding traits, it is equivalent to testing a static_cast
from B
to A
).
Besides my version is ill-formed:
error: expected primary-expression before 'a'
AFAU, I can not "declare" variable inside a `requires clause.
Is there a way to test for "is copy initializable from"? Possibly by fixing my concept?
Sounds like std::is_convertible_v<B, A>
, a.k.a. std::convertible_to<B, A>
.
The way that's traditionally implemented is to put the conversion in a function argument:
template<class T> T produce();
template<class T> void consume(T);
template<class A, class B>
concept can_copy_init_from =
requires { consume<A>(produce<B>()); };