Fix PR31916 - std::visit rejects visitors accepting lvalue arguments

A static assertion was misfiring since it checked
is_callable<Visitor, decltype(__variant_alt<T>.value)>. However
the decltype expression doesn't capture the value category as
required. This patch applies extra braces to decltype to fix
that.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@294612 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2017-02-09 19:01:22 +00:00
parent 5a0c9c3d7a
commit d8b62dceb2
2 changed files with 12 additions and 1 deletions

View File

@@ -578,7 +578,7 @@ private:
constexpr decltype(auto) operator()(_Alts&&... __alts) const { constexpr decltype(auto) operator()(_Alts&&... __alts) const {
__std_visit_exhaustive_visitor_check< __std_visit_exhaustive_visitor_check<
_Visitor, _Visitor,
decltype(_VSTD::forward<_Alts>(__alts).__value)...>(); decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
return __invoke_constexpr(_VSTD::forward<_Visitor>(__visitor), return __invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
_VSTD::forward<_Alts>(__alts).__value...); _VSTD::forward<_Alts>(__alts).__value...);
} }

View File

@@ -283,9 +283,20 @@ void test_exceptions() {
#endif #endif
} }
// See http://llvm.org/PR31916
void test_caller_accepts_nonconst() {
struct A {};
struct Visitor {
void operator()(A&) {}
};
std::variant<A> v;
std::visit(Visitor{}, v);
}
int main() { int main() {
test_call_operator_forwarding(); test_call_operator_forwarding();
test_argument_forwarding(); test_argument_forwarding();
test_constexpr(); test_constexpr();
test_exceptions(); test_exceptions();
test_caller_accepts_nonconst();
} }