public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r10-9937] libstdc++: Do not use deduced return type for std::visit [PR 100384] Date: Fri, 18 Jun 2021 12:56:28 +0000 (GMT) [thread overview] Message-ID: <20210618125628.E9B67386181D@sourceware.org> (raw) https://gcc.gnu.org/g:8ad4d9b46944db1be6f1b216b5b8e74bd9f66937 commit r10-9937-g8ad4d9b46944db1be6f1b216b5b8e74bd9f66937 Author: Jonathan Wakely <jwakely@redhat.com> Date: Tue May 4 12:16:46 2021 +0100 libstdc++: Do not use deduced return type for std::visit [PR 100384] This avoids errors outside the immediate context when std::visit is an overload candidate because of ADL, but not actually viable. The solution is to give std::visit a non-deduced return type. New helpers are introduced for that, and existing ones refactored slightly. libstdc++-v3/ChangeLog: PR libstdc++/100384 * include/std/variant (__get_t): New alias template yielding the return type of std::get<N> on a variant. (__visit_result_t): New alias template yielding the result of std::visit. (__same_types): Move into namespace __detail::__variant. (__check_visitor_results): Likewise. Use __invoke_result_t and __get_t. (__check_visitor_result): Remove. (visit): Use __visit_result_t for return type. * testsuite/20_util/variant/100384.cc: New test. (cherry picked from commit af5b2b911dd80ae9cc87404b7e7ab807cf6655d4) Diff: --- libstdc++-v3/include/std/variant | 28 ++++++++++++++++++++---- libstdc++-v3/testsuite/20_util/variant/100384.cc | 9 ++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 0a754fb4196..5f76d76490e 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -1053,6 +1053,25 @@ namespace __variant std::index_sequence<__indices...>> : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { }; + template<size_t _Np, typename _Variant> + using __get_t = decltype(std::get<_Np>(std::declval<_Variant>())); + + // Return type of std::visit. + template<typename _Visitor, typename... _Variants> + using __visit_result_t + = invoke_result_t<_Visitor, __get_t<0, _Variants>...>; + + template<typename _Tp, typename... _Types> + constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...); + + template <typename _Visitor, typename _Variant, size_t... _Idxs> + constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>) + { + return __same_types< + invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>... + >; + } + } // namespace __variant } // namespace __detail @@ -1238,7 +1257,8 @@ namespace __variant #endif template<typename _Visitor, typename... _Variants> - constexpr decltype(auto) visit(_Visitor&&, _Variants&&...); + constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> + visit(_Visitor&&, _Variants&&...); template<typename... _Types> inline enable_if_t<(is_move_constructible_v<_Types> && ...) @@ -1704,14 +1724,14 @@ namespace __variant } template<typename _Visitor, typename... _Variants> - constexpr decltype(auto) + constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> visit(_Visitor&& __visitor, _Variants&&... __variants) { if ((__variants.valueless_by_exception() || ...)) __throw_bad_variant_access("std::visit: variant is valueless"); - using _Result_type = std::invoke_result_t<_Visitor, - decltype(std::get<0>(std::declval<_Variants>()))...>; + using _Result_type + = __detail::__variant::__visit_result_t<_Visitor, _Variants...>; using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>; diff --git a/libstdc++-v3/testsuite/20_util/variant/100384.cc b/libstdc++-v3/testsuite/20_util/variant/100384.cc new file mode 100644 index 00000000000..4866aa017ff --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/variant/100384.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++17 } } + +#include <variant> + +int visit(int*, std::true_type) { return 0; } + +const std::true_type dat; + +int i = visit(nullptr, dat);
reply other threads:[~2021-06-18 12:56 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210618125628.E9B67386181D@sourceware.org \ --to=redi@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).