I am looking for a class that is like std::variant
that holds all types instead of one of the types.
So I would like to be able to write:
std::all_variant<int, double> av{1, 3.14159};
int i = std::get<int>(av); // i should be 1.
double d = std::get<double>(av); // d should be 3.14159
This is basically a tuple
but guarantees that each type appears only once so you can do std::get<Type>
instead of std::get<Index>
.
For context I want to be able to write the following code (so if there is a better way of doing that I would appreciate to know):
std::all_variant<int, double> av{1, 3.14159};
template <typename T> // T must be either int or double.
void MyFunc(std::all_variant<int, double> av) {
std::cout << std::get<T>(av);
}
int main() {
MyFunc<int>(av); // Should print 1.
MyFunc<double>(av); // Should print 3.14159.
MyFunc<std::string>(av); // Error! av doesn't have std::string variant.
}
I'm not sure what this would be called so I'm not sure if this is in the standard library. I guess it wouldn't be to hard to write one but I don't want to reinvent the wheel.
I am looking for a class that is like std::variant that holds all types instead of one of the types.
What you are looking for is called std::tuple
std::tuple<int,double> mytup( 1, 2.0 );
std::cout << std::get<int>( mytup ) << "\n"; // prints 1
std::cout << std::get<double>( mytup ) << "\n"; // prints 2
std::cout << std::get<std::string>( mytup ) << "\n"; // compiler error
Live example
As for single type appearance requirement you would get compilation error when you try to use std::get<type>
instead of index with std::tuple
with duplicated types. (thanks @max66)
In addition to Slava's answer, you can enforce type-uniqueness in a tuple using for example something like is_unique
from this post:
#include <tuple>
#include <type_traits>
// From https://stackoverflow.com/a/47511516
template <typename...>
inline constexpr auto is_unique = std::true_type{};
template <typename T, typename... Rest>
inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
(!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
>{};
// Tuple that only accept unique type parameters
template<typename... Ts>
using uniq_tuple = typename std::enable_if<is_unique<Ts...>, std::tuple<Ts...>>::type;
int main()
{
// Compiles
uniq_tuple<int, float> t1;
// Fails
uniq_tuple<int, float, int> t2;
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With