简体   繁体   English

从VS2008移植到VS2013时绑定中的错误C2668

[英]Error C2668 in bind while porting from VS2008 to VS2013

I'm trying to port my code from VS2008 to VS2013 and I'm getting some errors with std::bind. 我正在尝试将代码从VS2008移植到VS2013,并且std :: bind出现了一些错误。 The errors say error C2668: 'bind' : ambiguous call to overloaded function. 错误显示错误C2668:'bind':对重载函数的歧义调用。 Here's some code: 这是一些代码:

// Relevant prototypes:
class CLineaPlanta:public SomeBase { /*...*/ };
int SomeBase::TipoLinea()const;
void SomeBase::TipoLinea(int val);

// function paramater: const std::shared_ptr<CLineaPlanta>& lineasBuscar
// function parameter: int tipoLinea;

std::shared_ptr<CLineaPlanta> lineas;
std::remove_copy_if(lineasBuscar.begin(), lineasBuscar.end(),
std::back_inserter(lineas), 
        bind(std::not_equal_to<int>(), bind(&CLineaPlanta::TipoLinea, _1), tipoLinea));

This code worked in Visual Studio 2008, but gives the mentioned error in Visual Studio 2013. 该代码在Visual Studio 2008中有效,但在Visual Studio 2013中给出了所提到的错误。

Obviously, the compiler's having a hard time figuring out which version of TipoLinea() I'm trying to call. 显然,编译器很难确定我要调用哪个TipoLinea()版本。 If I rename the getter version to getTipoLinea, the error goes away. 如果我将getter版本重命名为getTipoLinea,该错误就会消失。

Just in case it is relevant, SomeBase is non-abstract and derives from CObject (not really sure why) and from an interface not related to this part of the code. 以防万一它是相关的,SomeBase是非抽象的,并且是从CObject(不确定原因)和与代码的这一部分无关的接口派生的。

Can anyone explain why VS2008 doesn't have any problem with this and how to prevent it (other than by renaming the function, of course)? 谁能解释为什么VS2008对此没有任何问题,以及如何防止它发生(当然不是通过重命名功能)?

I have no idea why this code ever worked in VS2008. 我不知道为什么这段代码曾经在VS2008中起作用。 It was probably a consequence of 2008's bind being implemented as a macro-based variadics emulation where bind had several overloads for each number of arguments being passed, one of them expecting the first argument to be a pointer to member function with the same number of arguments. 可能是2008年的bind被实现为基于宏的variadics仿真的结果,其中bind对于传递的每个参数数量都具有多个重载,其中一个期望第一个参数是指向具有相同参数数量的成员函数的指针。 This would allow the compiler to disambiguate because you pass one bound argument to bind , so it knows the function argument must have one parameter. 这将允许编译器消除歧义,因为您将一个绑定参数传递给bind ,因此它知道函数参数必须具有一个参数。

In VS2013, true variadics are used, but this probably means that the type of the first argument is more generic and so the compiler can no longer disambiguate. 在VS2013中,使用了真正的variadics,但这可能意味着第一个参数的类型更加通用,因此编译器不再歧义。 To make this compile, you need to explicitly cast the member pointer: 为了进行编译,您需要显式强制转换成员指针:

std::remove_copy_if(lineasBuscar.begin(), lineasBuscar.end(),
    std::back_inserter(lineas), 
    bind(std::not_equal_to<int>(),
         bind(static_cast<int (SomeBase::*)() const>(&CLineaPlanta::TipoLinea),
              _1),
             tipoLinea));

But as Neil Kirk said, rewriting to a lambda is easier: 但是正如Neil Kirk所说,重写为lambda会更容易:

std::remove_copy_if(lineasBuscar.begin(), lineasBuscar.end(),
    std::back_inserter(lineas),
    [tipoLinea](const std::shared_ptr<CLineaPlanta>& linea) {
        return linea->TipoLinea() != tipoLinea;
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM