英文:
run std::visit on the variant and original type
问题
有一个奇怪的情况,有时一个函数接受一个变体,而其他时候它接受变体的成员。
void branching_function(auto argument)
{
using typer = std::remove_reference<decltype(argument)>::type;
using variant_type = std::variant<int, double>;
// using variant_type = std::variant; <- doesn't work because missing <int, double> (here we could use a Concept over std::variant?)
if constexpr(std::is_same<typer, variant_type>::value)
{
// std::variant action (do visit)
std::visit([](auto argument_s){
(void)argument_s;
}, argument);
}
else
{
//非 std::variant 操作 (不执行 visit)
}
}
https://godbolt.org/z/xT1KcdK11
我可以使用 if constexpr
+ std::is_same
来测试是否处于变体情况,并获得预期的行为。
我正在努力找出如何将 std::is_same
测试泛化,以使条件适用于所有 std:: 变体。
C++ 中是否有一种类似 "is visitable" 的概念?
英文:
Have a strange case where sometimes a function takes a variant but other times it takes the member of the variant.
void branching_function(auto argument)
{
using typer = std::remove_reference<decltype(argument)>::type;
using variant_type = std::variant<int,double>;
// using variant_type = std::variant; <- doesn't work because missing <int, double> (here we could use a Concept over std::variant?)
if constexpr(std::is_same<typer, variant_type>::value)
{
// std::variant action (do visit)
std::visit([](auto argument_s){
(void)argument_s;
},argument);
}
else
{
//non std::variant action (don't do visit)
}
}
https://godbolt.org/z/xT1KcdK11
I can use a if constexpr
+ std::is_same
to test if i'm on the variant case and get the expected behavior.
I'm struggling to figure out how to generalize the std::is_same
test so that the condition applies to all std:: variants.
Is there some kind of "is visitable" concept in C++?
答案1
得分: 3
自从C++20以来,测试调用是否良好形成变得直观:
void branching_function(auto argument)
{
if constexpr(requires { std::visit([](auto){}, argument); })
{
std::visit([](auto argument_s){
(void)argument_s;
}, argument);
}
else
{
//非std::variant操作(不要进行访问)
}
}
这样做的好处是它将自动适用于argument
的任何类型,std::visit
也会接受这些类型。这不仅适用于std::variant
,还适用于公开派生自std::variant
的类(有一些限制)。
英文:
Since C++20 it is straight-forward to test whether a call is well-formed:
void branching_function(auto argument)
{
if constexpr(requires { std::visit([](auto){}, argument); })
{
std::visit([](auto argument_s){
(void)argument_s;
}, argument);
}
else
{
//non std::variant action (don't do visit)
}
}
The benefit of this is that it will automatically work with any type for argument
that std::visit
would accept. This isn't only std::variant
, but also classes publicly derived from std::variant
(with some restrictions).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论