获取参数包中的参数类型

时间:2015-12-05 19:45:39

标签: c++ templates c++11

所以,我们说我们有以下代码:

#include <stack>

template<class... Args>
auto make_stack(Args&&... args)
{
    std::stack<INSERT_TYPE_HERE> s;
    return s;
}

int main()
{
    auto s = make_stack(1, 2.2, 3); //would be std::stack<double>
    auto s2 = make_stack(1l, 2, 3); //would be std::stack<long>
}

如何在参数包中找到常见的参数类型?

2 个答案:

答案 0 :(得分:8)

使用<type_traits>中的std::common_type。它是一种类型特征,它提供了可以转换为所有类型的公共类型。所以在你的情况下你需要:

template<typename... Args>
auto make_stack(Args&&... args)
{
    using commonT = std::common_type_t<Args...>;
    std::stack<commonT> s;
    return s;
}

编辑正如@DietmarKühl在评论中提到的,如果您使用C ++ 11而不是C ++ 14,则可能需要在commonT上使用std::decay。看起来std::decay仅在结果类型上应用,因为C ++ 14。

答案 1 :(得分:0)

不幸的是,不能保证类型相同。
您可以使用std::common_type,但请注意(来自documentation):

  

确定所有类型T ...中的公共类型,即所有T ...的类型都可以隐式转换为。

这意味着它可能不是您期望的那种。

无论如何,通过查看您的示例,我认为您的问题可以通过下面的模板化函数和使用initializer_list轻松解决。 它遵循一个工作示例:

#include <initializer_list>
#include <stack>

template<typename T>
auto make_stack(std::initializer_list<T> list)
{
    std::stack<T> s;
    return s;
}

int main()
{
    auto s = make_stack<double>({1, 2.2, 3}); //would be std::stack<double>
    auto s2 = make_stack<long int>({1l, 2, 3}); //would be std::stack<long>
}