C++函数将重复参数绑定到curried函数

gan*_*ran 7 c++ gcc currying

我试图理解currying和调用一个函数的概念,该函数连接三个字符串,但只传递两个字符串并使用第二个参数两次.

但是,当我这样做时,第二个参数根本没有被发送到函数,它打印出一个空字符串.这是一个非常明显的错误吗?

string concatthreestrings(string a,string b,string c){
    cout<<"Value of A: "<<a<<endl;
    cout<<"Value of B: "<<b<<endl;
    cout<<"Value of C: "<<c<<endl;
    return a+b+c;
}


int main()
{
    typedef std::function< string( string,string) > fun_t ;
    using namespace std::placeholders;
    fun_t fn = std::bind( concatthreestrings, _1, _2, _2);
    cout<<endl<<fn( "First","Second")<<endl;

}
Run Code Online (Sandbox Code Playgroud)

这是给出以下输出.不使用_2两次意味着第二个参数将被传递给第二个和第三个.如果在其位置使用字符串,其工作正常.

在此输入图像描述

ipc*_*ipc 5

复制字符串很昂贵.由于std::bind认为占位符的值仅使用一次,因此它对std::move字符串执行a .这是针对每个参数完成的,因此,移动bc移动,这意味着空字符串.

您可以通过使用const-reference传递参数来明确说出您的意思来更改该行为:

string concatthreestrings(string const& a,string const& b,string const& c)
Run Code Online (Sandbox Code Playgroud)

现在,它应该工作.

  • 你确定这种行为是明确定义的吗?根据我在标准中读到的内容,`bind`返回的包装器将其参数转发给包装函数.在这种情况下,根据我的理解,我们将有这样的包装器(在推断模板参数和折叠之后):`string g(const char(&u1)[6],const char(&u2)[7]){ concatthreestrings(forward <const char(&)[6]>(u1),forward <const char(&)[7]>(u2),forward <const char(&)[7]>(u2)); }`.三个字符串`a`,`b`和`c`将由数组构成,所以我看不到移动会发生的位置. (2认同)