Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用标准函子进行curry_C++ - Fatal编程技术网

C++ 如何使用标准函子进行curry

C++ 如何使用标准函子进行curry,c++,C++,我有以下循环: MyList li; vector<Token*>::iterator itr = tokens.begin(); for (; itr != tokens.end(); ++itr) { li.add_string((*itr)->get_name()); } 不幸的是,我得到了那个讨厌的GCC模板编译错误 你能告诉我什么是正确的函子吗 我不能使用c++11 [编辑] 我的编译器不支持lamda 如果有帮助,以下是错误消息: /usr/lib/gcc

我有以下循环:

MyList li;
vector<Token*>::iterator itr = tokens.begin();
for (; itr != tokens.end(); ++itr) {
    li.add_string((*itr)->get_name());
}
不幸的是,我得到了那个讨厌的GCC模板编译错误

你能告诉我什么是正确的函子吗

我不能使用c++11

[编辑] 我的编译器不支持lamda

如果有帮助,以下是错误消息:

/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h: In instantiation of 'std::binder1st<std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> > >':
abc.c:823:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h:100: error: no type named 'second_argument_type' in 'class std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> >'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h:103: error: no type named 'first_argument_type' in 'class std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> >'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h:106: error: no type named 'first_argument_type' in 'class std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> >'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h:111: error: no type named 'second_argument_type' in 'class std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> >'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h:117: error: no type named 'second_argument_type' in 'class std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> >'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h: In function 'std::binder1st<_Operation> std::bind1st(const _Operation&, const _Tp&) [with _Operation = std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> >, _Tp = MyList*]':
abc.c:823:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/backward/binders.h:126: error: no type named 'first_argument_type' in 'class std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> >'
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/algorithm:62,
                 from abc.c:4:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_algo.h: In function '_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<Token**, std::vector<Token*, std::allocator<Token*> > >, _Funct = std::binder1st<std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> > >]':
abc.c:824:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_algo.h:4200: error: no match for call to '(std::binder1st<std::binder2nd<std::mem_fun1_t<void, MyList, const std::string&> > >) (Token*&)'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../include/c++/4.4.7/backward/binders.h:在“std::binder1st”的实例化中:
abc.c:823:从此处实例化
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../../../include/c++/4.4.7/backward/binders.h:100:错误:“class std::binder2nd”中没有名为“second_argument_type”的类型
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../../../include/c++/4.4.7/backward/binders.h:103:错误:“class std::binder2nd”中没有名为“first_argument_type”的类型
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../../../include/c++/4.4.7/backward/binders.h:106:错误:“class std::binder2nd”中没有名为“first_argument_type”的类型
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../../../include/c++/4.4.7/backward/binders.h:111:错误:“class std::binder2nd”中没有名为“second_argument_type”的类型
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../../../include/c++/4.4.7/backward/binders.h:117:错误:“class std::binder2nd”中没有名为“second_argument_type”的类型
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../../include/c++/4.4.7/backward/binders.h:在函数“std::binder1st std::binder1st std::bind1st(const\u Operation&,const\u Tp&)[with _Operation=std::binder2nd,\u Tp=MyList*]”中:
abc.c:823:从此处实例化
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../../../include/c++/4.4.7/backward/binders.h:126:错误:“class std::binder2nd”中没有名为“first_argument_type”的类型
在/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../include/c++/4.4.7/algorithm:62中包含的文件中,
来自abc.c:4:
/usr/lib/gcc/x86\u 64-redhat-linux/4.4.7/../../../../../../../../include/c++/4.4.7/bits/stl\u algo.h:在函数“\u Funct std::for_each(\u IIter,\u IIter,\u functt,\u functt)[with\u IIter=\u gnu cxx::\u normal u迭代器,\u Funct std::binder1st]”中:
abc.c:824:从此处实例化
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../../../../../../include/c++/4.4.7/bits/stl_-algo.h:4200:错误:调用“(std::binder1st)(令牌*&)”不匹配
[EDIT2]我现在知道为什么会出错了。bind2nd的实现如下:

  template<typename _Operation, typename _Tp>
    inline binder2nd<_Operation>
    bind2nd(const _Operation& __fn, const _Tp& __x)
    {
      typedef typename _Operation::second_argument_type _Arg2_type;
      return binder2nd<_Operation>(__fn, _Arg2_type(__x));
    }
模板
内联装订机2
bind2nd(常数运算和常数fn,常数Tp和常数x)
{
typedef typename_操作::第二个参数_type_Arg2_type;
返回binder2nd(uu fn,_Arg2_type(uu x));
}
_操作是MyList::add_string中的mem_fun\t,这很好,因为mem_fun\t提供了operator()API

这里的问题是:_Arg2_type(uux),因为_Arg2_type是_Operation::second_argument_type,但是mem_fun_t没有second_argument_type属性,因为它是一元函数的子类

如果有人能确认我的类型转换跟踪,我将非常感激

谢谢Eric,你提到“bind1st和bind2d要求值是常量”让我很激动(但我认为你的措辞本身并不正确,因为关键不是值必须是常量,而是值必须是某种类型)


最后,GCC扩展组合是最好的解决方案;我确信boost具有同等功能。

如果您的编译器支持它,您可以使用lambdas:

    for_each(tokens.begin(), tokens.end(), [&li] (Token * val)
    {
        li.add_string(val->get_name());
    } );

错误源于您试图将函数绑定为
MyList
add\u string
方法的第二个参数
bind1st
bind2nd
要求值为常量,不适合将函数作为要绑定的值来接收

对于_,每个
都需要一个函数,该函数将迭代器作为其第一个参数。如果您真的坚持对每个使用
,那么没有外部函数(相当于lambda,但不够优雅)就无法完成您想要完成的任务。此函数需要接收列表和令牌迭代器作为参数。然后,根据声明参数的顺序,可以使用
bind1st
bind2nd
将列表绑定到函数

让我们来看看这个函数:

void AddTokenNameToList(MyList& li, Token* token)
{
    li.add_string(token->get_name());
}
您可以将此
用于每个_

for_each(tokens.begin(), tokens.end(), std::bind1st(AddTokenNameToList, li));
如果列表参数被反转,您将使用bind2nd来绑定列表值

您可能会争辩说,这个函数是针对这种特殊情况定制的,不像只使用std方法那样优雅。我想你可能会发疯,把函数模板化,以接收应用于第一个参数和第二个参数的方法,但你真正想要的是一个lambda,因为你不能使用它们,这是你能得到的


然而,在这一点上,您不得不怀疑它是否真的节省了代码。这就是为什么bind1st和bind2nd名声不好,被认为几乎无用的原因之一。不过,它允许您使用其他一些不错的算法,因此它们仍然有一些优势。

这不是一个很好的替代方案。如果没有C++11的lambdas,您已经拥有的就可以了。您想要转换-但首先您必须调整MyList,以便它可以用于STL算法。如果您不能使用C++11,您可以使用Boost吗<代码>boost::bind
mem\u fun
@AlanStokes更有用,boost.Lambda;-)@模板不适用于直接函数调用。我一直认为Lambda库非常聪明,但从来没有发现它的用途。
for_each(tokens.begin(), tokens.end(), std::bind1st(AddTokenNameToList, li));