I am currently learning about concepts in C 20, and came across this example:
template <typename From, typename To>
concept is_convertible_without_narrowing = requires (From&& from) {
{ std::type_identity_t<To[]>{std::forward<From>(from)}} -> std::same_as<To[1]>;
};
I am curious if the following can be considered a correct alternative implementation of the above:
template <typename From, typename To>
concept is_convertible_without_narrowing = requires (From&& from) {
{ To{std::forward<From>(from)} } -> std::same_as<To>;
}
or, even simpler:
template <typename From, typename To>
concept is_convertible_without_narrowing = requires (From&& from, To&& to) {
to = {from};
}
CodePudding user response:
I am curious if the following can be considered a correct alternative implementation of the above:
The simple answer is no.
In the second version, To{std::forward<From>(from)}
can be regarded as constructing To
through initializer_list
, so is_convertible_without_narrowing<int, std::vector<int>>
will be true
.
Similarly, the third version can be regarded as assigning To
with initializer_list
, so is_convertible_without_narrowing<int, std::vector<int>&>
will also be true
.