没有匹配的调用错误存在的升压::参考,但不与的std :: REF [英] No matching call error occuring for boost::ref but not with std::ref

查看:135
本文介绍了没有匹配的调用错误存在的升压::参考,但不与的std :: REF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一些code,计数采用仿函数和 REF向量元素的数目绑定的boost :: 或的std :: (对于C ++ 11)的命名空间。我使用的是的#define 之间切换的boost :: 的std :: 命名空间。我使用升压版本1.53和我的编译命令是 G ++ TEST.CPP -std = C ++ 11 。我试着用gcc 4.7.2版本4.6.3和我得到同样的错误,既

我有3个问题:


  1. 我不明白这是对例2中产生的错误。

  2. 是否有可能使code这样的便携式只是切换的命名空间?

  3. 是否有一个很好的参考,详细描述了 STD 提振之间的差异的版本绑定​​ REF 函数? (我看了<一个href=\"http://stackoverflow.com/questions/10555566/is-there-any-difference-between-c11-stdbind-and-boostbind\">this的问题,但答案没有提及 REF 函数

谢谢!

P.S。这个例子只是说明我的问题,我知道尺寸()的std ::矢量: - )

  //#定义USE_STD#IFDEF USE_STD
的#include&lt;功能&GT;
使用命名空间std ::占位符;
命名空间IMPL = STD;
#其他
#包括LT&;升压/ version.hpp&GT;
#包括LT&;升压/ bind.hpp&GT;
#包括LT&;升压/ ref.hpp&GT;
命名空间IMPL =提振;
#万一#包括LT&;&iostream的GT;
#包括LT&;&算法GT;
#包括LT&;矢量&GT;类项目{
    INT ID_;上市:
    项(中间体ID):ID_(ID){};
};模板&LT; typename的项目&GT;
类计数器{
    INT count_;上市:
    //无效的typedef result_type的; //添加此修复例3时IMPL =提振
    计数器():count_(0){};
    void运算符()(ITEM *项目){_计数++;}
    INT运算符()(){返回count_;}
};// ------------------------------------------------ ------------------------------
INT主(INT ARGC,CHAR *的argv [])
{
的#ifndef USE_STD
    性病::法院LT&;&LT; BOOST_LIB_VERSION =&所述;&下; BOOST_LIB_VERSION&LT;&LT;的std :: ENDL;
#万一    //分配
    的typedef的std ::矢量&lt;项目* GT; ItemVec;
    ItemVec VEC;
    的for(int i = 0; I&LT; 9; ++ I){vec.push_back(新项目(I));}    //例1,同时适用于
    计数器&LT;项目&GT; F1;
    F1 =的std :: for_each的(vec.begin(),vec.end(),F1);
    性病::法院LT&;&LT; F1()=&LT;&LT; F1()&LT;&LT;的std :: ENDL;    //例2,作品有IMPL = STD ONLY
    //编译错误与IMPL =升压:敌不过呼叫'(的boost ::的reference_wrapper&lt;反向&LT;项目&GT;&GT;)(项目*放大器;)'
    计数器&LT;项目&GT; F2;
    的std :: for_each的(vec.begin(),vec.end(),implement执行:: REF(F2));
    性病::法院LT&;&LT; F2()=&LT;&LT; F2()&LT;&LT;的std :: ENDL;    //例3,作品有IMPL = STD ONLY
    //编译IMPL =升压ERROR无类型命名为'result_type的'类计数器&LT;项目&GT;'
    //这可以固定通过添加上述的typedef
    计数器&LT;项目&GT; F3;
    的std :: for_each的(vec.begin(),vec.end(),implement执行::绑定(implement执行:: REF(F3),_1));
    性病::法院LT&;&LT; F3()=&LT;&LT; F3()&LT;&LT;的std :: ENDL;    // 清理
    对于(ItemVec:迭代它= vec.begin(!);它= vec.end(); ++吧){
        删除它;
    }
    vec.clear();    返回0;
}


解决方案

例2失败的原因的 的boost ::的reference_wrapper 不具有的成员操作符()其中转发参数(S)不像的std ::的reference_wrapper 。正因为如此,这只是用于通过引用传递正常参数,而不是函数或者预期被称为仿函数是有用的。

3例失败,因为Boost.Bind 依靠特定的协议,让你通过,如果​​使用没有明确的返回类型的版本的函数或仿函数的结果类型。如果你传递一个指针到函数或指向成员函数中,returnd粘合剂对象有一个嵌套的 result_type的设定的返回类型说PTF或PTMF 。如果你通过一个仿函数,它需要一个嵌套的 result_type的。结果
的std ::绑定,在另一方面,根本没有嵌套 result_type的如果你的仿函数没有之一。

请注意,你可以,就像我说的,明确提供的结果类型既的boost ::绑定的std ::绑定

 的std :: for_each的(vec.begin(),vec.end(),implement执行::绑定&LT;无效&GT;(implement执行:: REF(F3),_1));
// ^^^^^^

,修正了榜样,使编译。

I've written some code which counts the number of elements of vector using a functor and the ref and bind templates from boost:: or std:: (for C++11) namespaces. I'm using a #define to switch between boost:: and std:: namespaces. I'm using boost version 1.53 and my compilation command is g++ test.cpp -std=c++11. I've tried with gcc versions 4.7.2 and 4.6.3 and I get the same errors with both.

I have 3 questions:

  1. I don't understand the error that is generated for Example 2.
  2. Is it possible to make code like this portable just by switching namespaces?
  3. Is there a good reference describing in detail the differences between the std and boost versions of bind, ref and function? (I saw this question but the answers don't mention ref or function)

Thanks!

P.S. The example just illustrates my problem, I know about size() for 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;
}

解决方案

Example 2 fails because boost::reference_wrapper doesn't have a member operator() which forwards the argument(s), unlike std::reference_wrapper. As such, it's only useful for passing normal arguments by reference, not functions or functors which are expected to be called.

Example 3 fails because Boost.Bind relies on a specific protocol to get the result type of the function or functor you pass, if you use the version without explicit return type. If you pass it a pointer-to-function or pointer-to-member-function, the returnd binder object has a nested result_type set to the return type of said PTF or PTMF. If you pass a functor, it needs a nested result_type.
std::bind, on the other hand, simply has no nested result_type if your functor doesn't have one.

Note that you can, as I said, explicitly provide the result type to both boost::bind and std::bind:

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

Which fixes the example and makes it compile.

这篇关于没有匹配的调用错误存在的升压::参考,但不与的std :: REF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆