【发布时间】:2014-01-10 08:48:05
【问题描述】:
我希望创建一个函数,如果传递了多个模板参数,则返回一个装箱的元组,如果只传递一个模板参数,则返回一个未装箱的值。
例如,我希望 foo<int>() 返回 int 和 foo<int, float> 返回类型为 std::tuple<int, float> 的内容。
我所有达到这个效果的尝试都失败了。
考虑以下使用 typetrait 结构的方法:
template<typename... T>
struct return_type {
typedef std::tuple<T...> type;
};
template<>
struct return_type<int> {
typedef int type;
};
// ... insert partial specializations for other supported primitive types
template<typename... T>
auto foo() -> typename return_type<T...>::type {
if (sizeof...(T) == 1)
return zap<T...>(); // Returns something of type T, where T is the first parameter
else
return bar<T...>(); // Assume this returns a std::tuple<T...>
}
由于foo 正文中的返回类型不同,这将无法编译。
或者,这里尝试使用decltype:
<template T>
T singular();
<template... T>
std::tuple<T...> multiple();
template <typename... T>
auto foo() -> decltype(sizeof...(T) == 1 ? singular() : multiple())
{
... // as above
}
这也将无法编译,因为三元运算符希望两个分支返回相同的类型。
最后,使用简单递归解包的幼稚方法也失败了:
template<typename T>
T foo() { return T{}; // return something of type T }
template<typename... T>
std::tuple<T...> foo() { return bar<T...>(); // returns a tuple }
这当然会失败,因为编译器无法确定要调用哪个重载函数。
我不明白为什么这样的事情在 C++11 中是不可能的,因为确定返回类型所需的所有信息都在编译时可用。然而,我正在努力寻找哪些工具可以让我做到这一点。任何帮助和建议将不胜感激。
【问题讨论】:
标签: c++ c++11 variadic-templates typetraits decltype