0

There are two classes with methods f() under the same name and signature:

struct A {
    void f() {}
};
struct B {
    void f() {}
};

Is it possible having a std::variant<A, B> v to call this method with a single expression instead of std::visit? Like v->f()?

Note: the question is specifically about std::variant. NOT about how to solve this particular task with without it (e.g. inheritance).

1 Answers1

4

You seem to be worried about the number of characters you have to type. Minimizing typing is not a design goal of the language. std::visit is the way to do what you want. And because this is the way there is no reason to provide a different way that would achieve the same.

If you want the same with less typing you can always write a custom function:

void f(auto& v) {
     std::visit( [](auto& x) { x.f(); },v );
}

Then you can call it via f(v);. Its not exactly the desired v->f(); but actually it has less characters to type.


PS: If this is for code golf, I want to refer you to this answer I wrote https://codegolf.stackexchange.com/a/251154/114229. It is discussing the trade off between adding some code to make certain expressions shorter (the answer is specifically about using #define but the same considerations apply to writing a function).

PPS: If this is not for code golf, I want to remind you that code is written only once, but read many times. Everybody can read std::visit(...) and there is plenty of documentation on how it works and what it does. There is zero documentation for the function f above and it has a really poor name. Readability is more important than faster typing.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • What if there are other methods? Is it possible to wrap this into a template? It doesn't look like so... – hopeless-programmer Feb 16 '23 at 12:36
  • @hopeless-programmer I answered the quesiton you asked, taking into consideration what you said in comments. Calling different methods would be a different question. Your `A` and `B` have only 1 method. If you want to ask a follow up question you can open a new quesiton – 463035818_is_not_an_ai Feb 16 '23 at 12:40
  • @hopeless-programmer however, then it is even less clear why you want to avoid `std::visit` – 463035818_is_not_an_ai Feb 16 '23 at 12:41
  • With 5 classes and 4 identical methods each call will take 5 lambdas with exactly the same content inside. What is the point of duplicating the code? – hopeless-programmer Feb 16 '23 at 12:50
  • @hopeless-programmer no. Why would you need 5 lambdas? You misunderstand something, but I cannot explain you why your code is wrong or unnecessary if you do not show the code. If you have an issue with 5 classes with 4 identical methods then you should open a new question to ask about that. – 463035818_is_not_an_ai Feb 16 '23 at 12:52
  • @hopeless-programmer oh well, I think I know what your misunderstanding is. If i am guessing right, look at the edit, it should already clarify something, 1 method, N different types -> only 1 lambda necessary – 463035818_is_not_an_ai Feb 16 '23 at 12:55
  • I never even imagined that this is possible with a single lambda. This is amazing! Thanks! – hopeless-programmer Feb 16 '23 at 13:22
  • @hopeless-programmer https://en.cppreference.com/w/cpp/utility/variant/visit all the examples on the page are about passing 1 callable to `std::visit` that can accept any of the alternatives. – 463035818_is_not_an_ai Feb 16 '23 at 14:23