Skip to content

Commit 10260aa

Browse files
committed
[libc++] Fix std::variant/std::invoke too eager instantiation
1 parent 740758a commit 10260aa

File tree

2 files changed

+31
-7
lines changed
  • libcxx

2 files changed

+31
-7
lines changed

libcxx/include/variant

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,13 +1182,21 @@ public:
11821182
_LIBCPP_HIDE_FROM_ABI constexpr variant(const variant&) = default;
11831183
_LIBCPP_HIDE_FROM_ABI constexpr variant(variant&&) = default;
11841184

1185-
template < class _Arg,
1186-
enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int> = 0,
1187-
enable_if_t<!__is_inplace_type<__remove_cvref_t<_Arg>>::value, int> = 0,
1188-
enable_if_t<!__is_inplace_index<__remove_cvref_t<_Arg>>::value, int> = 0,
1189-
class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1190-
size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1191-
enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1185+
template <class _Arg,
1186+
bool = !is_same_v<__remove_cvref_t<_Arg>, variant> && !__is_inplace_type<__remove_cvref_t<_Arg>>::value &&
1187+
!__is_inplace_index<__remove_cvref_t<_Arg>>::value,
1188+
class = void>
1189+
struct __arg_overload_type {};
1190+
1191+
template <class _Arg>
1192+
struct __arg_overload_type<_Arg, true, __void_t<__variant_detail::__best_match_t<_Arg, _Types...>>> {
1193+
using type _LIBCPP_NODEBUG = __variant_detail::__best_match_t<_Arg, _Types...>;
1194+
};
1195+
1196+
template <class _Arg,
1197+
class _Tp = typename __arg_overload_type<_Arg>::type,
1198+
size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1199+
enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
11921200
_LIBCPP_HIDE_FROM_ABI constexpr variant(_Arg&& __arg) noexcept(is_nothrow_constructible_v<_Tp, _Arg>)
11931201
: __impl_(in_place_index<_Ip>, std::forward<_Arg>(__arg)) {}
11941202

libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,28 @@ void test_vector_bool() {
173173
assert(std::get<0>(v) == true);
174174
}
175175

176+
struct ConvertibleFromAny {
177+
template <class V>
178+
ConvertibleFromAny(V) {}
179+
};
180+
176181
int main(int, char**) {
177182
test_T_ctor_basic();
178183
test_T_ctor_noexcept();
179184
test_T_ctor_sfinae();
180185
test_no_narrowing_check_for_class_types();
181186
test_construction_with_repeated_types();
182187
test_vector_bool();
188+
189+
{ // Check that the constraints are evaluated lazily
190+
struct Matcher {
191+
Matcher() {}
192+
Matcher(std::variant<ConvertibleFromAny>) {}
193+
};
194+
195+
Matcher vec;
196+
[[maybe_unused]] Matcher m = std::move(vec);
197+
}
198+
183199
return 0;
184200
}

0 commit comments

Comments
 (0)