在C ++ 11中,无论如何都要从具有指定模板参数的模板类中获取通用模板类?

时间:2016-11-29 17:36:12

标签: c++ c++11 templates typetraits

(例如从std::list获取std::list<some_value_type>

请考虑以下代码:

#include <list>
#include <string>

std::string combine(int val, std::string str)
{
    return std::to_string(val) + str;
}

template <class T, class U>
auto foo(const T &container, const U &val)
    -> std::list<U>
{
    using RetType = std::list<U>;
    RetType result;

    for(auto item : container) {
        result.push_back(combine(item, val));
    }

    return result;
}

int main()
{
    std::list<int> numbers = {1, 2, 3, 4, 5};
    std::list<std::string> result = foo(numbers, std::string(" potato"));
    return 0;
}

这编译,但我希望它的工作方式不同。我希望foo返回与第一个参数相同的容器,但是将其值类型更改为第二个参数的类型,即键入U

因此,如果foo作为第一个参数传递std::list<int>而第二个参数传递std::string,则返回std::list<std::string>。或者,如果foostd::vector<int>中作为其第一个参数传递,std::string作为其第二个参数,则返回std:: vector<std::string>。等等。

基本上我想将std::list<U>的两个实例替换为完成上述操作的内容,可能使用<type_traits>的工具。

有没有在C ++ 11中这样做?我发现的唯一解决方案是为我想要使用的每种容器类型创建foo的重载版本,但我更喜欢是否有一般方法来覆盖所有容器类型。

1 个答案:

答案 0 :(得分:4)

是的,您可以使用模板模板参数并将list<T>的每次出现更改为通用C<T>

template <template<class...>class C, class T, class U>
auto 
foo(const C<T> &container, const U &val) -> C<U>
{
  using RetType = C<T>;
  // ...
}

常用的替代方法是使用迭代器,迭代器是容器元素的通用接口。可以使用的标准算法是std::transform

transform(numbers.begin(), numbers.end(), inserter(result, result.begin()), [] (int n) {
  return combine(n, " potato");
});