繁体   English   中英

在VC2010中实现for(auto item:container)

[英]Implementing for(auto item : container) in VC2010

我想在VC2010中创建一个用于模拟(auto item:container)的小宏,然后在发布时将其替换为实际结构。

有BOOST_FOREACH,但是我想要自动支持。

我尝试创建一个宏。 但是,当取消引用的迭代器是常量类型时,它将失败。

#define _LIB_FOREACH_LINENAME_CAT(name, line) name##line
#define _LIB_FOREACH_LINENAME(name, line) _LIB_FOREACH_LINENAME_CAT(name, line)

#define LIB_AUTO_FOREACH(item, expr) \
    decltype((expr))&& _LIB_FOREACH_LINENAME(con, __LINE__)((expr)); auto _LIB_FOREACH_LINENAME(it, __LINE__) = _LIB_FOREACH_LINENAME(con, __LINE__).begin(); for(auto (item) = *_LIB_FOREACH_LINENAME(con, __LINE__).begin(); _LIB_FOREACH_LINENAME(it, __LINE__) != _LIB_FOREACH_LINENAME(con, __LINE__).end(); ++_LIB_FOREACH_LINENAME(it, __LINE__), (item) = *_LIB_FOREACH_LINENAME(it, __LINE__))

任何人都面临着纠正地雷或找到可行的实施方案的挑战?

编辑:

请注意,(expr)仅应评估一次。

有BOOST_FOREACH,但是我想要自动支持。

BOOST_FOREACH似乎支持C ++ 0x auto关键字。

就像您的宏一样,boost的宏更胜一筹。 它也适用于数组(可能是零终​​止的char数组),并允许您为循环变量使用引用,而不是凭空出现。

代替

decltype((expr))&&

你可能应该写

auto&&

您的方法存在的一个问题是,它不适用于不提供begin / end成员函数(例如数组)的范围。 拟议的C ++ 0x for-range循环利用免费的begin / end函数和依赖于参数的查找来解决此问题。

将代码块作为宏参数包括在内可能是一个好主意:

#include <cstddef>

namespace for_range_helpers {

template<class Container>
auto begin(Container& c) -> decltype(c.begin())
{ return c.begin(); }

template<class Container>
auto end(Container& c) -> decltype(c.end())
{ return c.end(); }

template<class T, std::size_t N>
T* begin(T (&array)[N])
{ return array+0; }

template<class T, std::size_t N>
T* end(T (&array)[N])
{ return array+N; }

} // namespace for_range_helpers

#define FOR_RANGE(init_,expression_,...) \
    do { \
        using ::for_range_helpers::begin; \
        using ::for_range_helpers::end; \
        auto&& range_ = expression_; \
        for (auto iter_ = begin(range_), end_ = end(range_); \
            iter_ != end_; ++iter_) \
        { \
            init_ = *iter_; \
            __VA_ARGS__ \
        } \
    } while (0)

#include <iostream>
#include <vector>

int main()
{
    int arr[] = {2,3,5,7,11};
    std::vector<int> vec;
    FOR_RANGE(auto i, arr,
        vec.push_back(i);
    );
    FOR_RANGE(auto i, vec,
        std::cout << ' ' << i;
    );
    std::cout << '\n';
}

在VS2010中,您还可以对每个扩展名使用Microsoft。 不过,就我个人而言,我更喜欢Boosts跨平台解决方案。

另请参阅此处

也许可以编写将C ++ 0x语法转换为Microsoft语法的宏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM