Reputation: 185
I'm trying to use std::visit
with the overload pattern. But I get an error when using the struct A by reference.
#include <variant>
#include <iostream>
template<class... Ts>
struct overload : Ts...
{
using Ts::operator()...;
consteval void operator()(auto&) const
{
static_assert(false, "ERROR");
}
};
template<typename T, typename...>
struct A {};
int main()
{
const std::variant<int, bool, A<int>> v{true};
std::visit(overload{
[](A<int> val) { /* works */ },
//[](A<int>& val) { /* does not work */ },
[](int val) { std::cout << val; },
[](bool val) { std::cout << std::boolalpha << val; },
},
v);
}
What's wrong here and how I could make it compile?
Edit:
error: static assertion failed: ERROR 11 | static_assert(false, "ERROR"); | ^~~~~ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14: note: in instantiation of function template specialization 'overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)>::operator()<const A>' requested here 56 | { return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); } | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:96:19: note: in instantiation of function template specialization 'std::__invoke_impl<void, overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)>, const A &>' requested here 91 | return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn), | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:1016:16: note: in instantiation of function template specialization 'std::__invoke<overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)>, const A &>' requested here 1011 | return std::__invoke(std::forward<_Visitor>(__visitor), | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:1032:14: note: in instantiation of member function 'std::__detail::__variant::__gen_vtable_implstd::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<void ()(overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)> &&, const std::variant<int, bool, A> &)>, std::integer_sequence<unsigned long, 2>>::__visit_invoke' requested here 1027 | decltype(__visit_invoke(std::declval<_Visitor>(), | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:968:48: note: in instantiation of member function 'std::__detail::__variant::__gen_vtable_implstd::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<void ()(overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)> &&, const std::variant<int, bool, A> &)>, std::integer_sequence<unsigned long, 2>>::_S_apply' requested here 963 | std::index_sequence<__indices..., __index>>::_S_apply(); | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:947:7: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all) 942 | (_S_apply_single_alt<false, __var_indices>( | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:932:2: note: in instantiation of function template specialization 'std::__detail::__variant::__gen_vtable_implstd::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<void ()(overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)> &&, const std::variant<int, bool, A> &), 3>, std::integer_sequence>::_S_apply_all_alts<0UL, 1UL, 2UL>' requested here 927 | _S_apply_all_alts( | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:1055:59: note: in instantiation of member function 'std::__detail::__variant::__gen_vtable_implstd::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<void ()(overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)> &&, const std::variant<int, bool, A> &), 3>, std::integer_sequence>::_S_apply' requested here 1050 | = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply(); | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:1724:45: note: in instantiation of static data member 'std::__detail::__variant::__gen_vtablestd::__detail::__variant::__deduce_visit_result<void, overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)> &&, const std::variant<int, bool, A> &>::_S_vtable' requested here 1719 | _Result_type, _Visitor&&, _Variants&&...>::_S_vtable; | ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/variant:1761:18: note: in instantiation of function template specialization 'std::__do_visitstd::__detail::__variant::__deduce_visit_result<void, overload<(lambda at prog_joined.cpp:28:18), (lambda at prog_joined.cpp:30:18), (lambda at prog_joined.cpp:31:18)>, const std::variant<int, bool, A> &>' requested here 1756 | return std::__do_visit<_Tag>( | ^ Line 22: Char 8: note: in instantiation of function template specialization 'std::visit<overload<(lambda at solution.cpp:28:18), (lambda at solution.cpp:30:18), (lambda at solution.cpp:31:18)>, const std::variant<int, bool, A> &>' requested here 22 | std::visit(overload{ | ^
Possible error on gcc 11.
Upvotes: 1
Views: 252
Reputation: 4091
const std::variant<int, bool, A<int>> // <—- Each variant is const. [const int, const bool and const A<int>]
Therefore the variants must be passed by either value or const lvalue reference.
But if the std::variant
is non-const, the variants must be passed by either value or lvalue reference.
Upvotes: 1