从模板模板方法参数中获取类型
Getting type from template template method parameters
我试图使一种方法,从容器类型中选择一个随机元素,如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;
}
,据我所知,它工作得很好。这并不是说就是好,只是它看起来就是。
我很快就不得不为另一个容器做同样的事情,所以我尝试使用模板模板参数使方法泛型:
template <template<typename element_t> container_t>
element_t pick_random(container_t from) { /* ... */ }
但是,这会抛出一个错误:
element_t does not name a type
我认为我的意图是足够清楚的,但重申一下:我试图获得列表的元素类型。我可以有一个单独的模板参数,但这样它就不能正确地推断类型。我尝试了各种不同的版本,但没有一个工作。
container_t
不是类型,container_t<T>
是。
您可以使用以下命令:
template <template<typename, typename...> C, typename T, typename...Ts>
T pick_random(const C<T, Ts...>& from);
对于std::vector
,您有一个分配器:std::vector<T, Alloc>
。
在c++ 14中,可以简单地使用auto
template <typename C>
auto pick_random(const C& from) { /* ... */ }
我不认为这里需要"模板模板参数",您可以简单地使用容器中的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;
}
value_type
——通过对迭代器解引用可获得的值的类型。来源:http://en.cppreference.com/w/cpp/iterator/iterator_traits
最好是避免对类模板的任意限制。毕竟,为什么不能从原始数组中选择一个元素呢?为了在c++ 11中正确命名类型,我们必须获得对begin
的非限定调用的结果,我们可以通过以下方式获得:
namespace detail {
using std::begin;
template <typename C>
auto adl_begin(C&& c) -> decltype(begin(std::forward<C>(c))) {
return begin(std::forward<C>(c));
}
}
using detail::adl_begin;
然后使用从任意容器中推导出element_type:
template <typename C>
auto pick_random(C& container) -> decltype(*adl_begin(container))
{ /* rest as before */ }
旁注:通过引用而不是通过值来获取容器。
如果您只使用标准库容器,那么您可以通过使用container_t::value_type
来获取存储类型。
template <typename container_t>
typename container_t::value_type pick_random(container_t& container)
{ ... }
相关文章:
- 获取 OID(类型::b_oid)作为 MongoDB C++驱动程序中的字符串
- 我可以使用 decltype() 或其他东西通过指针获取真实类型吗?
- 从两个 4x64 位整数数组中获取取模
- Qt/SQL - 从 QSqlQuery exec Stored Procedure 获取列类型和名称?
- 特征:从数组类型中获取标量类型是否记录?
- 在现代 c++ 中,有什么好方法可以获取 arg 类型列表表单函数指针吗?
- 从继承的C 类获取模板类型
- vulkan vulkan.hpp从对象实例中获取opbject类型
- 获取变量类型名称
- 从 csv 文件中获取不同类型的数据,并将其放入 C++ 中的 typedef 结构中
- 获取模板类型的类型
- 从 Mono Assembly.dll 中获取所有类型/类的列表C++
- 如何在折叠过程中获取成员类型的提升::mpl 占位符
- 如何在 c++ 中获取层类型咖啡
- 如何从 decltype a 引用中获取值类型
- 可以用于获取参数类型的 decltype
- 如何在 C++ 中获取映射类型指针,映射
- 从Hcursor获取光标类型
- 当可能的许多派生类型时,从基本类型的实例中获取派生类型
- 如何在C++中获取动态类型名称