我试图将我的代码从VS2008移植到VS2013,并且我在使用std :: bind时遇到了一些错误。 错误说错误C2668:'绑定' :模糊调用重载函数。 这是一些代码:
// 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));
此代码在Visual Studio 2008中有效,但在Visual Studio 2013中提供了上述错误。
显然,编译器很难弄清楚我试图调用哪个版本的TipoLinea()。如果我将getter版本重命名为getTipoLinea,则错误就会消失。
以防它是相关的,SomeBase是非抽象的,并且是从CObject(不确定为什么)和从与这部分代码无关的接口派生的。
任何人都可以解释为什么VS2008对此没有任何问题以及如何防止它(当然除了通过重命名功能)?
答案 0 :(得分:1)
我不知道为什么这个代码在VS2008中有效。这可能是因为2008 bind
被实现为基于宏的变量仿真,其中bind
对于传递的每个参数都有几个重载,其中一个期望第一个参数为是一个指向成员函数的指针,具有相同数量的参数。这将允许编译器消除歧义,因为您将一个绑定参数传递给bind
,因此它知道函数参数必须有一个参数。
在VS2013中,使用了真正的变量,但这可能意味着第一个参数的类型更通用,因此编译器无法再消除歧义。要进行此编译,您需要显式转换成员指针:
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));
但正如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;
});