c++ - 无法将参数 1 从 'overloaded-function' 转换为 '...'

标签 c++ boost function-pointers

现在我尝试使用 boost bind & mem_fn。 但是绑定(bind)重载函数有一个问题。 后续代码编译报错如何解决?

boost::function< void( IF_MAP::iterator ) > bmf = std::mem_fun1< void, IF_MAP, IF_MAP::iterator >( &IF_MAP::erase );
boost::function< void( IF_MAP::iterator ) > bmf = boost::mem_fn< void, IF_MAP, IF_MAP::iterator >( &IF_MAP::erase );

主要目的是编译后续代码

IF_MAP M;
boost::function< void( IF_MAP::iterator ) > bmf = boost::bind(
    boost::mem_fn< void, IF_MAP, IF_MAP::iterator >( &IF_MAP::erase ),
    &M, _1 );
M.insert( IF_MAP::value_type( 1, 1.f ) ); M.insert( IF_MAP::value_type( 2, 2.f ) );
bmf( 2 );

编译错误信息是这样的...

error C2665: 'boost::mem_fn' : none of the 2 overloads could convert all the argument types could be 'boost::_mfi::mf1 boost::mem_fn::iterator>(R (__thiscall std::map<_Kty,_Ty>::* )(A1))' or 'boost::_mfi::cmf1 boost::mem_fn::iterator>(R (__thiscall std::map<_Kty,_Ty>::* )(A1) const)'

附言 如你所知,std::map 有 3 个重载的删除成员函数

  1. void erase(迭代器_Where)
  2. size_type erase(const key_type& _Keyval)
  3. void erase(迭代器_First,迭代器_Last) 第二个功能可以很容易地绑定(bind),但其他功能则不然。

编辑
更详细地描述我的问题:

实际上,我想进行延迟函数调用。 当我遇到函数的返回码时,是时候进行范围分析了,所以应该调用延迟函数。

现在我正在重构一些遗留代码。现在,我通常会看到这种代码模式。 (实际代码更复杂,但几乎相同,如下所示) 重复的 erase() 调用分散在此函数中。

typedef map< int, float > IF_MAP;

bool DoAndPopOld( IF_MAP& M, int K )
{
    IF_MAP::iterator Itr = M.find( K );
    if ( Itr == M.end() ) return false;

    if ( K < 10 ) 
    {
        M.erase( Itr ); // erase call is here...
        return false;
    }

    if ( 100 < K )
    {
        // Do something
        M.erase( Itr ); // and here...
        return true;
    }

    // Do something
    M.erase( Itr ); // and also here!

    return true;
}

所以,我想像这样重构上面的代码......

class ScopedOutCaller
{
private:
    boost::function< void() > F;
public:
    ScopedOutCaller( boost::function< void() > _F ) : F(_F) {}
    ~ScopedOutCaller() { F(); } // deferred function call
};

bool DoAndPopNew( IF_MAP& M, int K )
{
    IF_MAP::iterator Itr = M.find( K );
    if ( Itr == M.end() ) return false;

    // Make deferred call, so I do not consider calling erase function anymore.
    ScopedOutCaller SOC( boost::bind( &IF_MAP::erase ), &M, Itr );

    if ( K < 10 ) 
    {
        // M.erase( Itr ); <-- unnecessary
        return false;
    }
    if ( 100 < K )
    {
        // Do something
        // M.erase( Itr ); <-- unnecessary
        return true;
    }

    // Do something
    // M.erase( Itr ); <-- unnecessary
    return true;
}

但是,正如我所问的……发生了编译错误。 我想要做的总而言之就是如何延迟函数调用。 请告诉我延期通话的方法。 谢谢。

最佳答案

std::map 的成员函数 erase() 已重载,因此您必须手动消除歧义 - 请参阅 Boost.Bind FAQ .

例如对于 size_type erase(const key_type&) 重载:

typedef IF_MAP::size_type (IF_MAP::*EraseType2)(const IF_MAP::key_type&);
boost::function<void (const IF_MAP::key_type&)> bmf2;
bmf2 = boost::bind((EraseType2)&IF_MAP::erase, &M, _1);

要选择其他版本,只需更改您要转换为的类型,例如:

// 1. void erase(iterator position) :
typedef void (IF_MAP::*EraseType1)(IF_MAP::iterator);
boost::function<void (IF_MAP::iterator)> bmf1;
bmf1 = boost::bind((EraseType1)&IF_MAP::erase, &M, _1);

// 3. void erase(iterator first, iterator last) :
typedef void (IF_MAP::*EraseType3)(IF_MAP::iterator, IF_MAP::iterator);
boost::function<void (IF_MAP::iterator, IF_MAP::iterator)> bmf3;
bmf3 = boost::bind((EraseType3)&IF_MAP::erase, &M, _1, _2);

遗憾的是 Visual Studio 在这里不符合 C++03(再次...),您必须使用以下两种形式:

typedef IF_MAP::iterator (IF_MAP::*EraseType1)(IF_MAP::const_iterator);
typedef IF_MAP::iterator (IF_MAP::*EraseType3)(IF_MAP::const_iterator,
                                               IF_MAP::const_iterator);

对于 VC8 和 VC9,您可以使用 _HAS_STRICT_CONFORMANCE 解决该问题, 但随着 C++0x 将 erase() 重载更改为 Dinkumware 使用的形式(参见 N3092, 23.4.1 ),这在 VC10 中再次中断。
为了可移植性,我会选择使用包装函数来解决这些烦人的问题;但是,如果您只关心 VC,请使用我上面提供的类型。

要在 block 导出处执行生成的仿函数,最简单的方法是使用 Boosts shared_ptr或类似的范围守卫。例如。对于 VC 特定类型转换:

typedef IF_MAP::iterator (IF_MAP::*EraseType)(IF_MAP::const_iterator);
boost::shared_ptr<void> guard(static_cast<void*>(0),
                              boost::bind((EraseType)&IF_MAP::erase, &M, Itr));

关于c++ - 无法将参数 1 从 'overloaded-function' 转换为 '...',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3725308/

相关文章:

c++ - 如何保护日志免受应用程序崩溃?

c++ - 底层 STL:在没有新 vector 的情况下将 std::vector 连接到自身

c - int (* f [])(); 和有什么区别和 int f[]();

c++ - 编译器误解了我的代码并向参数添加了额外的 "const"

C++如何表达一个数学术语

c++ - 当用户输入字符而不是 float 和整数时如何避免无限循环?

boost - 使用 boost::chrono 而不链接到它

c++ - 什么时候必须将 io_context 传递给 boost::asio::spawn? (C++)

c++ - ACE(C++ 库)是否仍用于高性能计算?

java - 将 getter/setter 作为方法引用传递