【问题标题】:BOOST_FOREACH implicit use of reference?BOOST_FOREACH 隐式使用引用?
【发布时间】:2010-03-02 08:35:34
【问题描述】:

我想知道在调用之前获取对向量的引用是否有任何好处 BOOST_FOREACH 或是否会自动使用返回引用的方法调用?例如以下两个循环中的哪一个将等价于第三个循环?

vector<float>& my_method();

void main()
{
    // LOOP 1 -------------------------------
    vector<float>& temp_vector = my_method();
    BOOST_FOREACH(float element, temp_vector)
        cout << element << endl;

    // LOOP 2 -------------------------------
    vector<float> temp_vector = my_method();
    BOOST_FOREACH(float element, temp_vector)
        cout << element << endl;

    // Which loop is this one most like? ----
    BOOST_FOREACH(float element, my_method())
        cout << element << endl;
}

【问题讨论】:

标签: c++ boost reference foreach


【解决方案1】:

快速测试表明该函数被调用了一次,并且与BOOST_FOREACH相关联没有发生复制。

#include <vector>
#include <iostream>
#include <boost/foreach.hpp>

struct X
{
    X() {}
    X(const X& ) { std::cout << "copied\n"; }
};

std::vector<X> vec(2);

//std::vector<X> method()
std::vector<X>& method()
{
    std::cout << "returning from method\n";
    return vec;
}

int main()
{
    BOOST_FOREACH(const X& x, method()) {}
}

【讨论】:

  • 感谢您提供出色的示例代码,如果 @Checkers 没有发布实际 boost 元编程的摘录,我会为您提供答案 :)
【解决方案2】:

查看BOOST_FOREACH 元编程的疯狂,我发现如果集合被复制了,它就会被复制

  1. 一个右值,
  2. “轻量级代理”,您可以通过专门化 boost::foreach::is_lightweight_proxy 为您的类型定义它。

因此,左值不会被复制。相反,它的指针被视为临时指针。

关键是这个:

# define BOOST_FOREACH_SHOULD_COPY(COL)             \
     (true ? 0 : boost::foreach_detail_::or_(       \
         BOOST_FOREACH_IS_RVALUE(COL)               \
       , BOOST_FOREACH_IS_LIGHTWEIGHT_PROXY(COL)))

然后它被用作函数的参数之一,用于将容器评估为临时变量:

template<typename T> 
inline auto_any<T> contain(T const &t, boost::mpl::true_ *) // rvalue 
{ 
    return t;
}

template<typename T>
inline auto_any<T *> contain(T &t, boost::mpl::false_ *) // lvalue
{
    // Cannot seem to get sunpro to handle addressof() with array types.
    #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x570))
    return &t;
    #else
    return boost::addressof(t);
    #endif
}

我的系统中安装了 Boost v1.38。

【讨论】:

    【解决方案3】:

    And although BOOST_FOREACH is a macro, it is a remarkably well-behaved one. It evaluates its arguments exactly once, leading to no nasty surprises

    所以my_method() 不会被多次调用

    从用户的角度来看,引用的行为类似于“正常”变量,您可以将引用完全视为原始变量。它对 foreach 循环没有影响。

    所以两个循环是等价的。

    【讨论】:

    • 没有解决问题的参考部分
    • 仍然没有真正解决核心问题,方法调用的结果必须存储在一个临时变量中......当它由宏来决定时,它是否会存储在一个引用中?或者将结果复制到新向量中(在过程中导致性能损失) - 请参阅更新的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    相关资源
    最近更新 更多