2016-11-29 88 views
0

(例如得到std::list<some_value_type>std::list在C++ 11中是否有從指定模板參數的模板類獲取通用模板類?

考慮下面的代碼:

#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的重載版本,但我更希望如果有一種通用的方法來實現它,它涵蓋所有容器類型。

回答

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"); 
}); 
+0

這並不支持自定義的分配(或hashers /比較器等,爲'set' /'unordered_set') –

+0

我不知道,你可以使用省略號當指定一個模板模板類時。謝謝! – GuyGizmo

+0

@ T.C。你是對的,但爲了我的目的,這已經夠好了。如果我確實需要使用自定義分配器,比較器或hashers,我可以使用像'template auto foo(const C &container,const U&val) - > C '。這將需要分配器/比較器可以採取任何一種類型,但我認爲它可以工作。 – GuyGizmo

相關問題