我不认为我的标题是准确的,所以只需转到代码。
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
之类的任何容器。我在没有任何lib(boost,QT等)的情况下搜索C98解决方案
事实上,我正在寻找类似C#的IEnumerable
。
有什么想法吗?
谢谢。
答案 0 :(得分:5)
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;
}
基本上每个容器都定义了成员typedef:
value_type
reference
const_reference
iterator
const_iterator
因此,如果您希望按值返回C::value_type
,可以使用C::reference
,如果您想通过引用返回,等等。
答案 1 :(得分:1)
我要做的是创建一个测试,检查您是否可以在容器上调用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;
}
答案 2 :(得分:0)
为什么要在C ++中使用IEnumerable,迭代器是迭代集合的好选择。