- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否有像 BOOST_FOREACH
这样的“for each”宏的实现?不需要 Boost?
最佳答案
我做了一个。
它应该适用于 GCC 和 MSVC 中的 C++11 右值引用,但我还没有很好地测试它,所以如果有任何错误请告诉我。
编辑:我添加了对字符串的支持。
#include <iterator>
#include <utility>
#define foreach(v, r) \
if (fe_detail::any const &fe_r_ = \
fe_detail::make_range(r)) { } else \
if (fe_detail::any const &fe_b_ = \
fe_detail::begin(fe_r_, ((void)0, 1) ? NULL : fe_detail::twrap(r))) { } else \
if (fe_detail::equal( \
fe_b_, \
fe_detail::end(fe_r_, ((void)0, 1) ? NULL : fe_detail::twrap(r)), \
((void)0, 1) ? NULL : fe_detail::twrap(r))) { } else \
for (bool fe_c_ = false; \
!fe_c_ && !fe_detail::equal( \
fe_b_, \
fe_detail::end(fe_r_, ((void)0, 1) ? NULL : fe_detail::twrap(r)), \
((void)0, 1) ? NULL : fe_detail::twrap(r)); \
fe_detail::advance(fe_b_, 1, ((void)0, 1) ? NULL : fe_detail::twrap(r))) \
for (v = (fe_detail::move(*fe_detail::iter(fe_b_, ((void)0, 1) ? NULL : fe_detail::twrap(r)))); \
fe_c_ = !fe_c_; )
namespace fe_detail
{
// Container traits
template<class C, class It> struct CT
{
typedef It It;
static It begin(C &c) { return c.begin(); }
static It end(C &c) { return c.end(); }
};
// Range traits
template<class R> struct RT : public CT<R, typename R::iterator> { };
template<class R> struct RT<R const> : public CT<R const, typename R::const_iterator> { };
template<class R> struct RT<R &> : public RT<R> { };
template<class T, bool B = T::value> struct enable_if;
template<class T> struct enable_if<T, true> { typedef T type; };
template<class T> struct is_char { static bool const value = false; };
template<class T> struct is_char<T const> : public is_char<T> { };
template<class T> struct is_char<T volatile> : public is_char<T> { };
template<> struct is_char<char> { static bool const value = true; };
template<> struct is_char<wchar_t> { static bool const value = true; };
template<class Ch> struct RT<Ch *> : enable_if<is_char<Ch> >
{
typedef Ch *It;
static It begin(It a) { return &a[0]; }
static It end(It a) { return &a[std::char_traits<Ch>::length(a)]; }
};
template<class R, size_t N> struct RT<R[N]>
{
typedef R *It;
static It begin(It a) { return &a[0]; }
static It end(It a) { return &a[N - (((void)0, is_char<R>::value) ? 1 : 0)]; }
};
template<class It> struct RT<std::pair<It, It> >
{
typedef It It;
static It begin(std::pair<It, It> const a) { return a.first; }
static It end(std::pair<It, It> const a) { return a.second; }
};
struct any { operator bool() const { return false; } };
template<class T> struct type_wrap { type_wrap(bool = false) { } };
template<class T> class wrap : public any
{ wrap &operator =(wrap const &); public: mutable T v; wrap(T v) : any(), v(v) { } };
template<class T> class wrap<T const> : public any
{ wrap &operator =(wrap const &); public: T const v; wrap(T const v) : any(), v(v) { } };
template<class T, size_t N> class wrap<T[N]> : public any
{ wrap &operator =(wrap const &); public: T (&v)[N]; wrap(T (&v)[N]) : any(), v(v) { } };
template<class T> class wrap<T const &> : public wrap<T const>
{ wrap &operator =(wrap const &); public: wrap(T const &v) : wrap<T const>(v) { } };
template<class T, size_t N> wrap<T[N]> make_range(T (&r)[N]) { return r; }
template<class T, size_t N> type_wrap<T[N]> twrap(T (&r)[N]) { throw 0; }
template<class It> type_wrap<std::pair<It, It> > twrap(std::pair<It, It> const &p) { throw 0; }
#if defined(_MSC_VER) && _MSC_VER >= 1600 || defined(__RVALUE_REFERENCE) || defined(__GXX_EXPERIMENTAL_CXX0X__)
template<class R> struct RT<R &&> : public RT<R> { };
template<class T> class wrap<T &&> : public wrap<T> { public: wrap(T &&v) : wrap<T>(std::move(v)) { } };
template<class R> wrap<R &&> make_range(R &&r) { return wrap<R &&>(std::forward<R>(r)); }
template<class R> type_wrap<R> twrap(R &&) { throw 0; }
using std::move;
#else
template<class R> wrap<R> make_range(R &r) { return r; }
template<class R> wrap<R const &> make_range(R const &r) { return r; }
template<class R> type_wrap<R> twrap(R &) { throw 0; }
template<class R> type_wrap<R const &> twrap(R const &) { throw 0; }
template<class T> T &move(T &v) { return v; }
template<class T> T const &move(T const &v) { return v; }
#endif
template<class R> wrap<typename RT<R>::It> begin(any const &r, type_wrap<R>)
{ return RT<R>::begin(static_cast<wrap<R> const &>(r).v); }
template<class R> wrap<typename RT<R>::It> end(any const &r, type_wrap<R>)
{ return RT<R>::end (static_cast<wrap<R> const &>(r).v); }
template<class R> bool equal(any const &i, any const &j, type_wrap<R>)
{ return static_cast<wrap<typename RT<R>::It> const &>(i).v == static_cast<wrap<typename RT<R>::It> const &>(j).v; }
template<class R> void advance(any const &i, typename std::iterator_traits<typename RT<R>::It>::difference_type const d, type_wrap<R>)
{ return std::advance(static_cast<wrap<typename RT<R>::It> const &>(i).v, d); }
template<class R> typename RT<R>::It &iter(any const &i, type_wrap<R>)
{ return static_cast<wrap<typename RT<R>::It> const &>(i).v; }
}
你可以像这样使用它:
#include <vector>
#include <iostream>
std::vector<int> make_vect()
{
std::vector<int> v;
v.push_back(5);
v.push_back(8);
v.push_back(10);
return v;
}
int main()
{
foreach (int c, make_vect())
{
std::cout << c << std::endl;
}
}
关于c++ - 没有 Boost 的 BOOST_FOREACH?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13834842/
我有一个包含一些数据的类,我想添加 begin()和 end()提供数据 ID 迭代器的函数。 我正在使用 Boost counting_iterator : #include #include
我正在编写 C++98(抱歉),但使用的是 C 库,它有许多对象存储在以下形式的数据结构中: struct c_container { size_t len; int data[1];
我尝试使用 Boost 库,我复制了整个 boost 文件夹,除了 docs、libs、more、status、tools 文件夹。 当我尝试使用下面的代码块时,我的编译器无法识别两件事。 vecto
我想使用 BOOST_FOREACH在我的代码库中使用我无法更改的遗留容器类型之一。 我在该类型上定义了以下方法: .length() 返回容器中元素的当前数量 .operator[](unsigne
我尝试在模板函数中使用 BOOST_FOREACH 和自定义但类型参数独立的迭代器。我收到 4-5 个错误,表明我的迭代器类没有很好地定义为迭代器。 在不使用 BOOST_FOREACH 的情况下重写
我想知道在调用之前获取对 vector 的引用是否有任何好处BOOST_FOREACH 或返回引用的方法调用是否会被自动使用?例如,以下两个循环中的哪一个将等同于第三个循环? vector& my_m
给定以下简单代码: list m_listOfOBjects; .... MyClass* ptrToMyClass; BOOST_FOREACH(MyClass object, m_listOfOb
我实现了一个简单的类 MyClass,其中有一个分配有 new 的数组(我知道我可以使用 STL 容器,但我试图理解他们是如何工作的)。我还创建了一个迭代器子类,能够迭代 MyClass 对象的所有元
我想使用 BOOST_FOREACH 宏来迭代我的 vector 中的一堆值。 vector 看起来像这样: struct _Element { int key; // more va
我测试了我的程序,并决定将 BOOST_FOREACH 宏更改为带有 const_iterator 的简单 for 循环。 我收到了意想不到的结果:使用 for 时程序运行速度变慢。 然后我写了一个小
我有一个 BOOST_FOREACH 循环来遍历列表。不幸的是,我还需要将迭代器缓存到特定项。 typedef List::iterator savedIterator; BOOST_FOREACH(
当使用BOOST_FOREACH时,下面的代码安全吗? BOOST_FOREACH (const std::string& str, getStrings()) { ... } ... std::
如果 BOOST_FOREACH 正在迭代的容器在 BOOST_FOREACH 范围内发生更改,会发生什么情况? BOOST_FOREACH 是否“卡住”初始状态? 最佳答案 在这种情况下,行为是未定
考虑以下代码,使用 BOOST_FOREACH 宏迭代一个侵入式列表: #include #include typedef boost::intrusive::list > MyList; voi
来自 boost doc , This results in near-optimal code generation; the performance of BOOST_FOREACH is usu
我有一个场景 vector ,vector .迭代元素的正确方法是什么,是否作为引用? 例如这个: BOOST_FOREACH(Scene scene, mScenes) { .....
我有以下宏: #define FOREACH(decl, c) BOOST_FOREACH(decl, std::make_pair((c).begin(), (c).end())) (我正在使用这个
我想听听您对 BOOST_FOREACH 使用的建议。 我已经阅读了它,因为它是一个非常沉重的标题,但实际上并不推荐它。 此外,它强制使用“break”和“continue”语句,因为您不能真正拥有由
我知道应该最后归咎于 boost 或编译器,但我在这里看不到其他解释。我正在使用 msvc 2008 SP1 和 boost 1.43。 在以下代码片段中,执行永远不会离开 第三个 BOOST_FOR
你可以使用 boost::filesystem 和 BOOST_FOREACH 遍历目录中的所有文件吗?我试过了 path dirPath = ... int fileCount = 0; BOOST
我是一名优秀的程序员,十分优秀!