从模板模板方法参数获取类型

Fun*_*uit 3 c++ templates c++11

我正在尝试创建一个从容器类型中选择随机元素的方法,比如std::vector.以前,我用这个:

std::string pick_random(std::vector<std::string> c) {
    int r = std::rand() % ids.size() + 1;
    auto it = c.begin();
    std::advance(it, r);
    return *it;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这很好.这并不是说这很好,只是它似乎是.

我很快就要为另一个容器做同样的事情,所以我尝试使用模板模板参数来使方法通用:

template <template<typename element_t> container_t>
element_t pick_random(container_t from) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

但是,这会引发错误:

element_t does not name a type
Run Code Online (Sandbox Code Playgroud)

我认为我的意图很清楚,但重申一下:我正在尝试获取列表的元素类型.我可以有一个单独的模板参数,但它无法正确推断出类型.我尝试了各种不同的版本,但都没有.

Jar*_*d42 6

container_t不是一种类型,container_t<T>是.

您可以使用以下内容:

template <template<typename, typename...> C, typename T, typename...Ts>
T pick_random(const C<T, Ts...>& from);
Run Code Online (Sandbox Code Playgroud)

至于std::vector你有分配器:std::vector<T, Alloc>.

在C++ 14中,您可以简单地使用 auto

template <typename C>
auto pick_random(const C& from) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)


ser*_*gej 5

我不认为这里需要"模板模板参数",你可以简单地使用value_type容器中的:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <list>

template <typename T>
typename T::value_type pick_random(T& from) {
    int r = std::rand() % from.size();
    auto it = from.begin();
    std::advance(it, r);
    return *it;
}

int main() {
    std::srand(std::time(0));

    std::vector<std::string> words {"the", "frogurt", "is", "also", "cursed"};
    std::list<int> numbers {1, 2, 3, 4, 5};

    std::cout << "words: "   << pick_random(words)   << std::endl;
    std::cout << "numbers: " << pick_random(numbers) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

value_type - 可以通过解除引用迭代器获得的值的类型.

资料来源:http://en.cppreference.com/w/cpp/iterator/iterator_traits