C++ std::for_每个忽略默认函数参数

C++ std::for_每个忽略默认函数参数,c++,boost,std,C++,Boost,Std,我偶然发现了一个奇怪的编译问题。我想使用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)

我偶然发现了一个奇怪的编译问题。我想使用
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 ;
}    
谢谢你的帮助


注意:我刚开始学习英语,很抱歉出错:)

默认参数只是一个代码生成工具,不是函数签名的一部分,因此您无法真正解决这个问题。您可以将函数包装到函数对象中,但这正是
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);

我认为它对函子来说根本不起作用。删除伪参数。我添加到
g
的伪参数是为了演示
std::for_each
的奇怪行为。用一些类似于
g(str)
wstring str
调用
g
就像一个符咒,但不是在
std::for_each
中。在我的例子中,如果没有技巧,直接使用
boost::algorithm::trim
作为函子是不可能的,因为它的第二个参数是可选的(一个std::locale)@Overcoder:这是因为
g(str)
立即变成
g(str,0)
——默认参数只是代码生成糖。这是我从代码中所期望的,但事实并非如此。以下是MinGW报告的内容:d:\development\tools\mingw32\bin\../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_algo.h:4185:2:错误:参数太少function@overcoder:这并不“奇怪”。此外,如果您坚持当前标准,请查看bind2nd(确实它对函数有一些要求-你的g应该是从二进制函数继承的结构)@vnm:是的,很好,少了一个boost依赖项:
std::for_each(…,…,std::bind2nd(boost::algorithm::trim,std::locale())
。谢谢!我会看看是否可以为我当前的项目启用C++0x。Lambdas似乎更方便。@过度编码:由你决定——绑定语法并不是那么糟糕,只是味道的问题。在这里有这一行并不是世界末日,它仍然是非常自解释的代码。。。
auto trimmer = std::bind(boost::algorithm::trim<std::wstring>, std::placeholders::_1, std::locale());

std::for_each(text.begin(), text.end(), trimmer);
std::for_each(text.begin(), text.end(), [](std::wstring & s){ boost::algorithm::trim<std::wstring>(s); });