【问题标题】:Using Boost::ref correctly..?正确使用 Boost::ref ..?
【发布时间】:2009-07-08 01:29:03
【问题描述】:

我怎样才能让它编译?错误是当我开始使用 boost::ref() 时。我认为 boost::ref 用于传递对 C++ 算法类的引用?

  list<Object> lst;
  lst.push_back(Object(1,2.0f));
  lst.push_back(Object(3,4.3f));

  struct between_1_and_10
  {
    int d;
    void operator() (Object& value) 
    { 
      value.a += 5; value.b -= 3.3f; 
      cout << d << endl;
      d += value.a;
    }
  };

  between_1_and_10 val;
  val.d = 4;
  for_each(lst.begin(), lst.end(), boost::ref(val));   // Problem is here
  printf("rg");

编辑这是人们建议的编译器错误:

1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\algorithm(29) : error C2064: term does not evaluate to a function taking 1 arguments
1>        c:\users\swangrun\desktop\minescout work\feat-000-gettargetimages\minescouttest\maintest.cpp(102) : see reference to function template instantiation '_Fn1 std::for_each<std::list<_Ty>::_Iterator<_Secure_validation>,boost::reference_wrapper<T>>(_InIt,_InIt,_Fn1)' being compiled
1>        with
1>        [
1>            _Fn1=boost::reference_wrapper<main::between_1_and_10>,
1>            _Ty=Object,
1>            _Secure_validation=true,
1>            T=main::between_1_and_10,
1>            _InIt=std::list<Object>::_Iterator<true>
1>        ]

【问题讨论】:

  • 好的。它应该在 for_each() 行。但是有什么问题。您要么必须向我们提供错误或足够的代码,以便我们可以重现错误。
  • 问题是它不能编译。我已接受答案,感谢您的参与!
  • Martin 的意思是“复制错误消息的文本并将其粘贴到您的问题中”。这样,我们可以向您解释编译器在说什么。它可能为您提供了查找错误所需的所有信息。至少,您应该这样做,以便搜索编译器错误文本的其他人可以找到问题及其答案。
  • 谢谢!很抱歉误解了您的意图。

标签: c++ boost


【解决方案1】:

boost::reference_wrapper(这是boost::ref 返回的内容)不会使operator() 过载。您可以将它与boost::bind 一起使用,它对其进行了特殊处理(不使用ref 会使bind 复制提供的函数对象)。

但是for_each 返回它调用这些东西的函数对象。所以就这样做吧

between_1_and_10 val;
val.d = 4;
val = for_each(lst.begin(), lst.end(), val);
printf("rg");

它将调用复制的val 上的内容,并返回上次调用后的函数对象。


只是告诉你在哪里可以使用boost::ref,因为你似乎误用了它。想象一个模板,它通过值获取其参数,并调用另一个函数:

void g(int &i) { i++; }

template<typename T>
void run_g(T t) { g(t); }

如果你现在想用一个变量来调用它,它会复制它。通常,这是一个合理的决定,例如,如果您想将数据作为启动参数传递给线程,您可以将其从本地函数复制到线程对象中。但有时,您可能不想复制它,而是实际传递一个引用。这就是boost::reference_wrapper 提供帮助的地方。下面的内容确实符合我们的预期,并输出1

int main() { 
  int n = 0; 
  run_g(boost::ref(n)); 
  std::cout << n << std::endl;
}

对于绑定参数,副本是一个很好的默认值。它还很容易使数组和函数衰减为指针(通过引用接受会使T 可能成为数组/函数类型,并会导致一些讨厌的问题)。

【讨论】:

    【解决方案2】:

    这是你真正想要的:

    for_each(lst.begin(), lst.end(), boost::bind<void>(boost::ref(val),_1  ) );
    

    编辑:根据 OP 的要求进行一些解释。回想一下 for_each() 接受一个函数,但您只是将一个对您的结构的引用传递给它(是的,该结构的 operator() 重载但您没有传递它)。 bind() 基本上“公开”了结构内的函数。

    EDIT2:“_1”的解释可以在下面的 cmets 中找到。

    【讨论】:

    • 谢谢。正是我想要的。如果不是太麻烦,您能否详细说明为什么需要绑定..那个看起来很有趣的_1是什么?对不起,我是 Boost 的新手。 (当然,除非你刚刚使用的技术有很好的教程。)
    • Bind 可能是必要的,因为编译器无法推断包装在 boost:ref 中的函数的返回类型。至于“_1”,你可以在这里阅读:boost.org/doc/libs/1_39_0/libs/bind/bind.html#with_functions
    • -1,_1 是 lambda 占位符。它实际上代表了 for_each 的迭代器所指向的“当前”项。
    • 是的,没有冒犯,但编辑解释实际上很奇怪。
    【解决方案3】:

    尝试不使用 boost::ref。

    【讨论】:

      猜你喜欢
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      相关资源
      最近更新 更多