![](/img/trans.png)
[英]How can I transform int to string then join with std::ranges::views?
[英]how can i avoid the compiler error: std::transform?
这是我的C ++代码(我使用的是Visual C ++ 2010):
int absd(int t)
{
return abs(t);
}
int main()
{
try
{
int dpi = 137;
int dpiCriterionAry[] = {100, 150, 200, 300, 400, 500, 600};
std::vector<int> vec(dpiCriterionAry, dpiCriterionAry + _countof(dpiCriterionAry));
std::transform(vec.begin(), vec.end(), vec.begin(), std::bind1st(std::minus<int>(), dpi));
std::transform(vec.begin(), vec.end(), vec.begin(), absd);
//std::transform(vec.begin(), vec.end(), vec.begin(), abs);
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, "\t"));
cout << endl;
}
catch(exception& e)
{
cerr << e.what() << endl;
}
return 0;
}
当我取消注释该行时:
//std::transform(vec.begin(), vec.end(), vec.begin(), abs);
我收到了错误消息:
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 ==========
但是,代码行:
std::transform(vec.begin(), vec.end(), vec.begin(), absd);
能行得通。 事实上,我使用的是相同的功能: abs
,我对结果感到困惑。 此外,我想知道是否可以将以下两行代码合并为一行(即一个std::transform
调用,具有相同的效果):
std::transform(vec.begin(), vec.end(), vec.begin(), std::bind1st(std::minus<int>(), 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));
关于你的最后一个问题,是的,lambdas在这里起了作用的作用:
std::transform(vec.begin(), vec.end(), vec.begin(), [&](int i) { return absd(dpi - i); } );
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' ?
你可以告诉它的编译器abs
,你的意思是它明确地转换成你的意思是函数的类型:
std::transform(vec.begin(), vec.end(), vec.begin(), (int (*)(int))abs);
或者通过创建一个引用所需函数的变量:
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)));
或者对于C ++ 03,您可以使用boost::bind
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.