如何避免编译器错误:std::transform? 这是我的C++代码(我使用Visual C++ 2010):

如何避免编译器错误:std::transform? 这是我的C++代码(我使用Visual C++ 2010):,c++,visual-c++,stl,compiler-errors,genetic-algorithm,C++,Visual C++,Stl,Compiler Errors,Genetic Algorithm,我收到了错误消息: 1>------ Build started: Project: Console, Configuration: Release Win32 ------ 1>Build started 2012/10/16 21:17:19. 1>InitializeBuildStatus: 1> Creating "..\Intermediate\Console.unsuccessfulbuild" because "AlwaysCreate" was spe

我收到了错误消息:

1>------ Build started: Project: Console, Configuration: Release Win32 ------ 
1>Build started 2012/10/16 21:17:19. 1>InitializeBuildStatus: 1>  Creating "..\Intermediate\Console.unsuccessfulbuild" because "AlwaysCreate" was specified. 1>ClCompile: 1>  Console.cpp
1>Console.cpp(16): error C2780: '_OutIt std::transform(_InIt1,_InIt1,_InIt2,_OutIt,_Fn2)' : expects 5 arguments - 4 provided 
1>          D:\ProgramFiles\VS 2010\VC\include\algorithm(1155) : see declaration of 'std::transform'
1>Console.cpp(16): error C2914: 'std::transform' : cannot deduce template argument as function argument is ambiguous 
1>Console.cpp(16): error C2914: 'std::transform' : cannot deduce template argument as function argument is ambiguous 
1>Console.cpp(16): error C2784: '_OutIt std::transform(_InIt,_InIt,_OutIt,_Fn1)' : could not deduce template argument for '_OutIt' from 'std::_Vector_iterator<_Myvec>' 
1>          with 
1>          [ 
1>              _Myvec=std::_Vector_val<int,std::allocator<int>> 
1>          ] 
1>          D:\ProgramFiles\VS 2010\VC\include\algorithm(1051) : see declaration of 'std::transform' 
1> 
1>Build FAILED. 
1> 
1>Time Elapsed 00:00:02.48 ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
我可以工作。事实上,我使用的是相同的函数:
abs
,我对结果感到困惑。 此外,我想知道是否可以将以下两行代码合并为一行(即一个
std::transform
调用,效果相同):

std::transform(vec.begin()、vec.end()、vec.begin()、std::bind1st(std::minus()、dpi));
std::transform(vec.begin()、vec.end()、vec.begin()、absd);

有人能帮我回答这两个问题吗?

问题是
std::abs
有。这就是为什么编译器无法找出您试图在
std::transform
函数调用中使用的重载

为了修复它,您可以按照@Xeo在其评论中提到的方法进行操作:

std::transform(vec.begin(), vec.end(), vec.begin(), [&](int i){ return abs(i); });
或者,您可以通过静态强制转换来获取适当的函数地址:

std::transform(vec.begin(), vec.end(), vec.begin(), static_cast<int(*)(int)>(abs));

abs
是一个重载函数,不是单个实体,因此对
std::transform
的调用无法推断模板参数,因为名称
abs
没有引用单个函数

这相当于:

void foo(int) { }
void foo(const char*) { }

template<typename T>
int bar(T)
{ return 0; }

int i = bar(foo);  // which 'foo' ?
或者通过创建引用所需函数的变量:

int (*p)(int) = abs;
std::transform(vec.begin(), vec.end(), vec.begin(), p);
要将这两个转换组合成一个,您可以使用lambda,正如Xeo所建议的,或者使用
std::bind

using std::placeholders::_1;
int (*p)(int) = abs;
std::transform(vec.begin(), vec.end(), vec.begin(),
               std::bind(p, std::bind(std::minus<int>(), dpi, _1)));
使用std::占位符::_1;
int(*p)(int)=abs;
std::transform(vec.begin(),vec.end(),vec.begin(),
std::bind(p,std::bind(std::minus(),dpi,_1));

或者对于C++03,您可以使用
boost::bind

重载函数不能很好地在通用上下文中用作函数指针。自使用VS2010以来最简单的解决方案:使用lambda<代码>标准::转换(vec.begin(),vec.end(),vec.begin(),[&](int i){return abs(dpi-i);})你很棒,你能告诉我第二个问题的解决方案吗:我想知道是否有可能将以下两行代码合并为一行(即一个std::transform调用,效果相同):std::transform(vec.begin(),vec.end(),vec.begin(),std::bind1st(std::minus(),dpi));std::transform(vec.begin()、vec.end()、vec.begin()、absd)@凯旋当然,好了,回答得很好。第二个问题如何:我想知道是否可以将以下两行代码合并为一行(即一个std::transform调用,效果相同):std::transform(vec.begin(),vec.end(),vec.begin(),std::bind1st(std::minus(),dpi));std::transform(vec.begin()、vec.end()、vec.begin()、absd);正如我所说的,请参阅Xeo的评论,或者我编辑了答案以显示如何使用
bind
hi执行此操作,我遇到了编译错误:使用std::placeholder::\u 1;int(*p)(int)=abs;std::transform(vec.begin(),vec.end(),vec.begin(),std::bind(p,std::bind(std::minus(),dpi,_1));错误消息:1>D:\ProgramFiles\VS 2010\VC\include\xxcallfun(7):错误C2664:“int(int)”无法将参数1从“std::tr1::\u Bind\u fty”转换为“int”
std::transform(vec.begin(), vec.end(), vec.begin(), static_cast<int(*)(int)>(abs));
std::transform(vec.begin(), vec.end(), vec.begin(), [&](int i) { return absd(dpi - i); } );
void foo(int) { }
void foo(const char*) { }

template<typename T>
int bar(T)
{ return 0; }

int i = bar(foo);  // which 'foo' ?
std::transform(vec.begin(), vec.end(), vec.begin(), (int (*)(int))abs);
int (*p)(int) = abs;
std::transform(vec.begin(), vec.end(), vec.begin(), p);
using std::placeholders::_1;
int (*p)(int) = abs;
std::transform(vec.begin(), vec.end(), vec.begin(),
               std::bind(p, std::bind(std::minus<int>(), dpi, _1)));