对于boost :: ref没有匹配的调用错误,但是对于std :: ref没有

mkm*_*mkm 6 c++ boost c++11 boost-ref

我已经写了一些代码进行计数用算符和矢量的元素的数量ref和bind模板从boost::或std::(对于C++ 11)的命名空间.我正在使用a #define来切换boost::和std::名称空间.我正在使用boost版本1.53,我的编译命令是g++ test.cpp -std=c++11.我已经尝试过使用gcc版本4.7.2和4.6.3,但两者都有相同的错误.

我有3个问题:

  1. 我不明白为例2生成的错误.
  2. 是否可以通过切换命名空间来使这样的代码成为可移植的?
  3. 是否有一个很好的参考,详细描述之间的差异std和boost版本bind,ref和function?(我看到了这个问题,但答案没有提及ref或function)

谢谢!

PS这个例子只是说明了我的问题,我知道size()了std::vector:-)

//#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;
}
Run Code Online (Sandbox Code Playgroud)

Xeo*_*Xeo 4

示例 2 失败,因为boost::reference_wrapper没有转发参数的成员operator(),这与std::reference_wrapper. 因此,它仅适用于通过引用传递普通参数,而不适用于预期调用的函数或函子。

示例 3 失败,因为如果您使用没有显式返回类型的版本, Boost.Bind依赖特定协议来获取您传递的函数或函子的结果类型。如果将函数指针或成员函数指针传递给它,则返回的绑定器对象将具有一个result_type指向所述 PTF 或 PTMF 返回类型的嵌套集。如果您传递函子,它需要一个嵌套的result_type.
std::bind另一方面,result_type如果您的函子没有嵌套,则根本没有嵌套。

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

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

这修复了示例并使其编译。