模板 Class return 元组或值,取决于参数包
Template Class return tuple or value, depend on parameter pack
我想写一个class,它有一个参数包和一个函数。这个函数应该 return 值本身,如果包中只有一种类型,否则它应该 return 一个元组。
如果 pack 是空的,它可以 return 空元组或 void,我不介意。
类似这样的东西(伪代码):
template<typename ...Args>
class A{
std::tuple<Args...> data;
#if sizeof...(Args)
std::tuple<Args...> get();
#else
Args[0] get();
#endif
};
我认为我目前的解决方案非常复杂,如果 Args 为空则不起作用。
当前解决方案:
template<bool EnableBool = true>
typename std::enable_if<
EnableBool && std::tuple_size_v<decltype(data)> == 1, typename std::tuple_element<0, decltype(data)>::type>::type
get();
从 C++17 开始,您可以使用 if constexpr
并且 return 类型将由编译器推导:
template<typename ...Args>
class A{
std::tuple<Args...> data;
public:
auto get()
{
if constexpr (sizeof...(Args) > 1)
return data;
else if constexpr (sizeof...(Args) == 1)
return std::get<0>(data);
else
return;
}
};
int main (int argc, char *argv[])
{
A<int,double> a;
static_assert(std::is_same_v<decltype(a.get()),std::tuple<int,double>>);
A<> b;
static_assert(std::is_same_v<decltype(b.get()),void>);
A<int> c;
static_assert(std::is_same_v<decltype(c.get()),int>);
我想写一个class,它有一个参数包和一个函数。这个函数应该 return 值本身,如果包中只有一种类型,否则它应该 return 一个元组。 如果 pack 是空的,它可以 return 空元组或 void,我不介意。
类似这样的东西(伪代码):
template<typename ...Args>
class A{
std::tuple<Args...> data;
#if sizeof...(Args)
std::tuple<Args...> get();
#else
Args[0] get();
#endif
};
我认为我目前的解决方案非常复杂,如果 Args 为空则不起作用。
当前解决方案:
template<bool EnableBool = true>
typename std::enable_if<
EnableBool && std::tuple_size_v<decltype(data)> == 1, typename std::tuple_element<0, decltype(data)>::type>::type
get();
从 C++17 开始,您可以使用 if constexpr
并且 return 类型将由编译器推导:
template<typename ...Args>
class A{
std::tuple<Args...> data;
public:
auto get()
{
if constexpr (sizeof...(Args) > 1)
return data;
else if constexpr (sizeof...(Args) == 1)
return std::get<0>(data);
else
return;
}
};
int main (int argc, char *argv[])
{
A<int,double> a;
static_assert(std::is_same_v<decltype(a.get()),std::tuple<int,double>>);
A<> b;
static_assert(std::is_same_v<decltype(b.get()),void>);
A<int> c;
static_assert(std::is_same_v<decltype(c.get()),int>);