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)
我认为我的意图很清楚,但重申一下:我正在尝试获取列表的元素类型.我可以有一个单独的模板参数,但它无法正确推断出类型.我尝试了各种不同的版本,但都没有.
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)
我不认为这里需要"模板模板参数",你可以简单地使用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