gpt4 book ai didi

c++ - boost::ref 没有发生匹配调用错误,但 std::ref 没有

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:31:51 30 4
gpt4 key购买 nike

我已经编写了一些代码,使用仿函数和 boost:: 中的 refbind 模板计算 vector 元素的数量> 或 std::(对于 C++11)命名空间。我正在使用 #defineboost::std:: 命名空间之间切换。我使用的是 boost 版本 1.53,我的编译命令是 g++ test.cpp -std=c++11。我已经尝试使用 gcc 版本 4.7.2 和 4.6.3,但我在这两个版本上都遇到了同样的错误。

我有 3 个问题:

  1. 我不明白为示例 2 生成的错误。
  2. 是否可以仅通过切换命名空间来使这样的代码具有可移植性?
  3. 是否有很好的引用资料详细描述了 bindstdboost 版本之间的差异,ref功能? (我看到了 this 问题,但答案没有提到 reffunction)

谢谢!

附言这个例子只是说明了我的问题,我知道 std::vectorsize() :-)

//#define USE_STD

#ifdef USE_STD
#include <functional>
using namespace std::placeholders;
namespace impl = std;
#else
#include <boost/version.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
namespace impl = boost;
#endif

#include <iostream>
#include <algorithm>
#include <vector>

class Item {
int id_;

public:
Item(int id) : id_(id) {};
};

template <typename ITEM>
class Counter {
int count_;

public:
// typedef void result_type; // adding this fixes Example 3 when impl=boost
Counter() : count_(0) {};
void operator()(ITEM* item) {count_++;}
int operator()() {return count_;}
};

//------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
#ifndef USE_STD
std::cout << "BOOST_LIB_VERSION=" << BOOST_LIB_VERSION << std::endl;
#endif

// allocate
typedef std::vector<Item*> ItemVec;
ItemVec vec;
for (int i = 0; i < 9; ++i) {vec.push_back(new Item(i));}

// Example 1, works for BOTH
Counter<Item> f1;
f1 = std::for_each(vec.begin(), vec.end(), f1);
std::cout << "f1()=" << f1() << std::endl;

// Example 2, works with impl=std ONLY
// COMPILE ERROR with impl=boost: "no match for call to ‘(boost::reference_wrapper<Counter<Item> >) (Item*&)’"
Counter<Item> f2;
std::for_each(vec.begin(), vec.end(), impl::ref(f2));
std::cout << "f2()=" << f2() << std::endl;

// Example 3, works with impl=std ONLY
// COMPILE ERROR with impl=boost "no type named ‘result_type’ in ‘class Counter<Item>’"
// this can fixed by adding the typedef described above
Counter<Item> f3;
std::for_each(vec.begin(), vec.end(), impl::bind(impl::ref(f3), _1));
std::cout << "f3()=" << f3() << std::endl;

// clean up
for (ItemVec::iterator it = vec.begin(); it != vec.end(); ++it) {
delete *it;
}
vec.clear();

return 0;
}

最佳答案

示例 2 失败,因为 boost::reference_wrapper没有 member operator() which forwards the argument(s) ,与 std::reference_wrapper 不同。因此,它仅对通过引用传递普通参数有用,对预期被调用的函数或仿函数没有用。

示例 3 失败,因为 Boost.Bind relies on a specific protocol to get the result type of the function or functor you pass ,如果您使用没有显式返回类型的版本。如果您将指向函数的指针或指向成员函数的指针传递给它,则返回的 Binder 对象有一个嵌套的 result_type 设置为所述 PTF 或 PTMF 的返回类型。如果你传递一个仿函数,它需要一个嵌套的 result_type
另一方面,std::bind 如果您的仿函数没有嵌套 result_type,则根本没有。

请注意,正如我所说,您可以显式地向 boost::bindstd::bind 提供结果类型:

std::for_each(vec.begin(), vec.end(), impl::bind<void>(impl::ref(f3), _1));
// ^^^^^^

修复示例并使其编译。

关于c++ - boost::ref 没有发生匹配调用错误,但 std::ref 没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15074148/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com