Vorac
Vorac

Reputation: 9114

Generic polymorphism: create a variable of whatever type and use it

I believe this is also called "type erasure". Consider the following not too minimal and not working code example:

#include <string>
#include <tuple>


std::pair<int, int> foo(int);
std::pair<std::string, std::string> foo(std::string);


struct S
{
    S(int);
    S(std::string);
};



int main()
{
    const auto some_bool{ false };

    const auto data =
    [ some_bool ]
    ()
    {
        if(some_bool)
        {
            return foo(42);
        }
        else
        {
             return foo("fourty-two");  // error: different return type
        }
    }
    ();

    const auto s{ data.first };

    // use s and data.second regardless of it's type
}

I would like to:

What would be a nice approach?

Upvotes: 0

Views: 88

Answers (1)

user4442671
user4442671

Reputation:

In order to be able to use .first and .second on data, you will need a pair of two type-erased values, as you need to avoid erasing the fact that it is a pair. i.e std::pair<erased_type, erased_type>

In your example, you know the list of types ahead of time, so you should use std::variant<> to create a type that can contain one of the known alternatives. If you do not know the list at compilation time, you can use std::any instead.

using int_or_string = std::variant<int, std::string>;
using data_type = std::pair<int_or_string, int_or_string>;

Next, you can force the lambda to return this erased type and let the various return values be implicitly converted to it:

[...]
    using int_or_string = std::variant<int, std::string>;
    const auto data =
    [ some_bool ]
    () -> std::pair<int_or_string, int_or_string>
    {
[...]

Upvotes: 1

Related Questions