在变体和原始类型上运行 std::visit。

huangapple go评论83阅读模式
英文:

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; &lt;- doesn&#39;t work because missing &lt;int, double&gt; (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&lt;decltype(argument)&gt;::type;
    using variant_type = std::variant&lt;int,double&gt;;
    // using variant_type = std::variant; &lt;- doesn&#39;t work because missing &lt;int, double&gt; (here we could use a Concept over std::variant?)
    if constexpr(std::is_same&lt;typer, variant_type&gt;::value)
    {
        // std::variant action (do visit)
        std::visit([](auto argument_s){
            (void)argument_s;
        },argument);
    }
    else
    {
        //non std::variant action (don&#39;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&#39;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).

huangapple
  • 本文由 发表于 2023年1月9日 08:59:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75052362.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定