mapbox / variant

C++11/C++14 Variant
BSD 3-Clause "New" or "Revised" License
371 stars 100 forks source link

Have a otherwise (else) type for match function #140

Closed sezaru closed 7 years ago

sezaru commented 7 years ago

Considering the example code bellow:

using Properties = mapbox::variant<Center, Indent, Justify, None>;

auto foo(const Properties & properties)
{
  return properties.match([](Center) { return bar1(); },
                          [](Indent) { return bar2(); });
}

The code will not compile because I don't have a lambda function match for Justify and None, but let's say that in both cases, I want to call the function bar3(), the code will need to be like that:

  return properties.match([](Center) { return bar1(); },
                          [](Indent) { return bar2(); },
                          [](Justify) { return bar3(); },
                          [](None) { return bar3(); });

Now, this works fine, but imagine that I have a larger variant type, it will begin to become tiresome to always have to create a lambda for all matches when they all call the same lambda.

What I propose is a special type otherwise, which will act like a default on a switch, meaning that if no match occurs for a specific type, otherwise will be called instead.

The code could be rewritten like that:

  return properties.match([](Center) { return bar1(); },
                          [](Indent) { return bar2(); },
                          [](otherwise) { return bar3(); });
daniel-j-h commented 7 years ago

There already is such a feature in the language: auto!

v.match([](Center) { },
        [](auto)   { });

This should work just fine. Requires C++14. Depending on the type and how generic your use-case is you want to capture by auto&&.

I don't think we should try to emulate this behavior for C++ before C++14.

daniel-j-h commented 7 years ago

Here's your small self-contained test case with a working "otherwise" matcher https://github.com/mapbox/variant/pull/141/files

sezaru commented 7 years ago

Oh, how silly of me, it didn't passed in my mind that I could use auto as a else in this context. Thanks!

daniel-j-h commented 7 years ago

No worries, great to see use-cases for .match coming up :)

chenzunfeng commented 3 years ago

But I am still courious at how to deal with this usecase on C++11. There is a macro DECLARE_VALUE_TYPE_ACCESOR defined in mapbox/feature.hpp, I tried to make it compilable on C++11.