我偶然发现了一个奇怪的编译问题.我想使用处理字符串列表std::for_each.以下简化代码说明了问题:
# include <list>
# include <string>
# include <algorithm>
using namespace std ;
void f(wstring & str)
{
// process str here
}
void g(wstring & str, int dummy = 0)
{
// process str here, same as f, just added a second default dummy argument
}
int main(int, char*[])
{
list<wstring> text ;
text.push_back(L"foo") ;
text.push_back(L"bar") ;
for_each(text.begin(), text.end(), f) ; // OK, fine :)
for_each(text.begin(), text.end(), g) ; // Compilation error, complains about
// g taking 2 arguments, but called within std::for_each
// with only one argument.
// ...
return 0 ;
}
Run Code Online (Sandbox Code Playgroud)
我使用MinGW 4.5.2和MSVC10进行了测试,两者都报告了相同的错误消息.最初,我想boost::algorithm::trim用作传递给std::for_each它的处理函数,但我发现它需要两个参数,第一个是必需的(要处理的字符串),第二个是可选的(提供空间字符定义的语言环境).
当使用std::for_each具有默认参数的函数或方法时,有没有办法在使用(和其他标准算法)时保持清洁?我发现了一种让它工作的方法,但它不再清晰易懂,因此for循环开始变得更容易......
# include <list>
# include <string>
# include <algorithm>
# include <boost/bind.hpp>
# include <boost/algorithm/string.hpp>
using namespace std ;
using namespace boost ;
// ... somewhere inside main
list<wstring> text ;
for_each(text.begin(), text.end(), bind(algorithm::trim<wstring>, _1, locale()) ;
// One must deal with default arguments ...
// for_each(text.begin(), text.end(), algorithm::trim<wstring>) would be a real pleasure
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助 !
注意:我刚开始学习英语,对不起错误:)
默认参数只是一个代码生成工具,而不是函数签名的一部分,因此您无法真正解决这个问题.你可以将你的函数包装在一个函数对象中,但这正是你bind已经为你做的.
但是,在C++ 0x中,您可以方便地存储结果(和使用std::bind),以使代码更具可读性:
auto trimmer = std::bind(boost::algorithm::trim<std::wstring>, std::placeholders::_1, std::locale());
std::for_each(text.begin(), text.end(), trimmer);
Run Code Online (Sandbox Code Playgroud)
(你不想在C++ 98/03中这样做的原因是返回类型bind是相当不雅观的,你不会通过拼写来帮助任何人.)
或者,再次在C++ 0x中,您可以使用lambda:
std::for_each(text.begin(), text.end(), [](std::wstring & s){ boost::algorithm::trim<std::wstring>(s); });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
754 次 |
| 最近记录: |