Is there any way to check number of template parameters and compile time? I would like to do this (this is not real code):
template<typename... Types>
class Foo
{
// Enable this if count of 'Types' is 1.
Types[0] Bar()
{
return Types[0]{};
}
// Enable this otherwise.
std::variant<Types> Bar()
{
return std::variant<Types>{};
}
};
Is there any way to achieve this?
CodePudding user response:
Not like that, at least not easily. You can probably add some helper struct that defines a type with if constexpr
and sizeof...()
and then use helper::return_type
or seomthing.
But I think this calls for template specialization:
#include <variant>
template<typename... Types>
class Foo
{
std::variant<Types...> Bar()
{
return {};
}
};
// Specialize for just one Type
template<typename Type>
class Foo<Type>
{
Type Bar()
{
return {};
}
};
CodePudding user response:
One option is to add a template parameter and then leverage constexpr if to check if the pack is empty or not like
template<typename first_t, typename... rest_t>
class Foo
{
auto Bar()
{
if constexpr (sizeof...(rest_t) == 0)
return first_t{};
else
return std::variant<first_t, rest_t...>{};
}
};
CodePudding user response:
It's not too hard to create a alias template for the type by specializing a helper type:
template<class...Ts>
struct ReturnTypeHelper : std::type_identity<std::variant<Ts...>> {};
template<class T>
struct ReturnTypeHelper<T> : std::type_identity<T> {};
template<class...Ts>
using ReturnType = typename ReturnTypeHelper<Ts...>::type;
template<typename... Types>
class Foo
{
public:
auto Bar()
{
return ReturnType<Types...>{};
}
};
static_assert(std::is_same_v<decltype(std::declval<Foo<int>>().Bar()), int>);
static_assert(std::is_same_v<decltype(std::declval<Foo<int,float>>().Bar()), std::variant<int, float>>);