Reputation: 9114
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:
data
constantif...else
s
.What would be a nice approach?
Upvotes: 0
Views: 88
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