如何仅使用容器进行模板
How can I template with container only?
本文关键字:何仅使 更新时间:2023-10-16
我认为我的标题不准确,所以只需转到代码。
namespace Fobaizer
{
template <typename T, typename C>
static T GetItemFromContainer(const C &container) {
T item = container[0]; // do something. 0 or iterator
return item;
}
}
例:
MyClass myClass = Fobaizer::GetItemFromContainer<MyClass, vector<MyClass>(myVector);
或
MyClass myClass = Fobaizer::GetItemFromContainer<MyClass, deque<MyClass>(myDeque);
这里 C 是任何容器,如 std::deque
或 std::vector
。我搜索没有任何库(升压、QT 等)的 C98 解决方案。
事实上,我正在寻找类似 C# IEnumerable
的东西。
知道吗?
谢谢。
template <typename C>
static typename C::value_type GetItemFromContainer(const C & container) {
typename C::value_type item = container[0]; // do something. 0 or iterator
return item;
}
基本上每个容器都定义了成员类型定义:
value_type
reference
const_reference
iterator
const_iterator
因此,如果要按值返回,C::reference
如果要按引用返回,则可以只使用 C::value_type
,等等。
我要做的是创建一个测试来检查是否可以在容器上调用std::begin
和std::end
。 然后对这些容器和std::advance
使用迭代器,将迭代器推进到需要它们的位置。
这种方法的优点是你可以接受不会重载operator[]
的容器(例如std::list
)
#include <utility>
#include <type_traits>
#include <vector>
#include <list>
namespace sfinae_true_details
{
template <class>
struct sfinae_true : std::true_type{};
}
template <class T>
auto test_has_begin_end(int) ->
sfinae_true_details::sfinae_true<decltype(std::begin(std::declval<T>()) ==
std::end(std::declval<T>())>;
template <class>
std::false_type test_has_begin_end(long);
template <class T>
struct has_begin_end : decltype(test_has_begin_end<T>(0)){};
int main()
{
static_assert(has_begin_end<std::vector<int> >::value, "");
static_assert(has_begin_end<std::list<float> >::value, "");
static_assert(has_begin_end<int>::value, "Expected to fail here");
return 0;
}
那么你的用法将是:
template <typename T, typename C>
static T GetItemFromContainer(const C &container) {
static_assert(has_begin_end<C>::value, "Must pass a container for which "
"std::begin and std::end are callable");
T item = *std::begin(container); // do something. 0 or iterator
auto iter = std::begin(container);
std::advance(iter, 5);
item = *iter; // equivalent to container[5] for RandomAccessContainers
return item;
}
为什么要在C++中执行 IEnumerable,迭代器是迭代集合的不错选择。
相关文章:
- 如何使布尔变量仅在设置为 true 时才为真?
- 如何使特定程序仅从安装的路径运行以避免DLL劫持
- 如何使虚函数接受仅在派生类中定义的数据类型?
- scanf() 的宽度说明符 - 要使用的字符长度在编译时不固定,仅在运行时确定.如何使其可变?
- 如何使QLineSeries/QXYSeries仅显示一个点标签
- 如何使 gdb 仅输出到文件
- 复制构造函数是始终隐式定义,还是仅在使用时定义?
- 如何实现构造函数,使其仅接受使用 typeid 的输入迭代器?
- 如何对 int 变量应用验证,使其仅接受整数数据,并且在任何其他数据的情况下不会出错?
- 如何对字符串变量应用验证,使其仅接受来自用户的字母数据?
- 提升序列化仅适用于主要?当我在其他对象中使用时,继续说"has no member named ‘serialize’"
- 如何使 BLE 服务器仅在状态更改时通知.
- 试图使循环仅检查字符串是否仅数字,而在编程中允许的C IM中允许的负数是一个类项目
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- 是否可以使整数仅收到一个单个数字而不是两个接收输入
- 如何使继承的类与父类仅在C++中的一个值不同
- 仅当捕获组最后一次出现时,才使字符成为可选字符
- 如何使函数模板仅适用于特定命名空间中的类型
- 如何仅使输出打印一次
- C++11编译器何时会使RVO和NRVO优于移动语义和常量引用绑定