C++ 带有函子的自动类型推断不起作用

C++ 带有函子的自动类型推断不起作用,c++,c++11,bind,std,stdbind,C++,C++11,Bind,Std,Stdbind,可能重复: void foo0(int val){std::cout我猜std::bind周围的括号会让解析器认为您正在声明名为applyWithFoo0和applyFoo1的函数 bind返回一个functor,auto应该能够检测它的类型 试试这个: int main(int argc, char* argv[]) { auto applyWithFoo0 = std::bind(foo0, std::placeholders::_

可能重复:


void foo0(int val){std::cout我猜std::bind周围的括号会让解析器认为您正在声明名为applyWithFoo0和applyFoo1的函数

bind返回一个functor,auto应该能够检测它的类型

试试这个:

 int main(int argc, char* argv[]) {
    auto                applyWithFoo0  =     std::bind(foo0,     std::placeholders::_1);
    //std::function<void (int)> applyWithFoo0        std::bind(foo0,     std::placeholders::_1) ); // use this instead to make compile
    auto                applyFoo1   =    std::bind(foo1, std::placeholders::_1, applyWithFoo0);
    foo2(123, applyFoo1);
}
intmain(intargc,char*argv[]){
autoapplyWithFoo0=std::bind(foo0,std::占位符::_1);
//std::函数applyWithFoo0 std::bind(foo0,std::占位符::_1));//改为使用此函数进行编译
autoapplyfoo1=std::bind(foo1,std::占位符::\u1,applyWithFoo0);
foo2(123,applyFoo1);
}

我猜std::bind周围的括号会让解析器认为您正在声明名为applyWithFoo0和applyFoo1的函数

bind返回一个functor,auto应该能够检测它的类型

试试这个:

 int main(int argc, char* argv[]) {
    auto                applyWithFoo0  =     std::bind(foo0,     std::placeholders::_1);
    //std::function<void (int)> applyWithFoo0        std::bind(foo0,     std::placeholders::_1) ); // use this instead to make compile
    auto                applyFoo1   =    std::bind(foo1, std::placeholders::_1, applyWithFoo0);
    foo2(123, applyFoo1);
}
intmain(intargc,char*argv[]){
autoapplyWithFoo0=std::bind(foo0,std::占位符::_1);
//std::函数applyWithFoo0 std::bind(foo0,std::占位符::_1));//改为使用此函数进行编译
autoapplyfoo1=std::bind(foo1,std::占位符::\u1,applyWithFoo0);
foo2(123,applyFoo1);
}

问题在于
std::bind
处理“绑定表达式”(就像您的
applyWithFooo0
)与其他类型不同。它不使用
applyWithFoo0
作为参数调用foo1,而是尝试调用
applyWithFoo0
并将其返回值传递给foo1。但是
applyWithFoo0
不会返回任何可转换为
std::function
的内容。处理“绑定表达式”的意图这样做是为了使它们易于组合。在大多数情况下,您可能不希望将绑定表达式作为函数参数传递,而只希望将其结果传递。如果将绑定表达式显式包装到
函数
对象中,则
函数
对象将直接传递给foo1,因为它不是“绑定表达式”因此不是由
std::bind
专门处理的

考虑以下示例:

#include <iostream>
#include <functional>

int twice(int x) { return x*2; }

int main()
{
  using namespace std;
  using namespace std::placeholders;
  auto mul_by_2 = bind(twice,_1);
  auto mul_by_4 = bind(twice,mul_by_2); // #2
  auto mul_by_8 = bind(twice,mul_by_4); // #3
  cout << mul_by_8(1) << endl;
}
其中,
noeval
告诉bind不要对表达式求值,而是直接将其传递给函数。但也许另一种方法——明确告诉bind将函子的结果传递给函数——会是一种更好的设计:

auto mul_by_8 = bind( twice, eval(mul_by_4) );

但是我想,现在已经太晚了…

问题是
std::bind
处理“bind expression”(就像你的
applyWithFoo0
)与其他类型不同。它不使用
applyWithFoo0
作为参数调用foo1,而是尝试调用
applyWithFoo0
并将其返回值传递给foo1。但是
applyWithFoo0
不会返回任何可转换为
std::function
的内容。处理“绑定表达式”的意图这样做是为了使它们易于组合。在大多数情况下,您可能不希望将绑定表达式作为函数参数传递,而只希望将其结果传递。如果将绑定表达式显式包装到
函数
对象中,则
函数
对象将直接传递给foo1,因为它不是“绑定表达式”因此不是由
std::bind
专门处理的

考虑以下示例:

#include <iostream>
#include <functional>

int twice(int x) { return x*2; }

int main()
{
  using namespace std;
  using namespace std::placeholders;
  auto mul_by_2 = bind(twice,_1);
  auto mul_by_4 = bind(twice,mul_by_2); // #2
  auto mul_by_8 = bind(twice,mul_by_4); // #3
  cout << mul_by_8(1) << endl;
}
其中,
noeval
告诉bind不要对表达式求值,而是直接将其传递给函数。但也许另一种方法——明确告诉bind将函子的结果传递给函数——会是一种更好的设计:

auto mul_by_8 = bind( twice, eval(mul_by_4) );

但是我想,现在已经太迟了…

最令人烦恼的解析错误?没有帮助。最令人烦恼的解析错误?没有帮助。只使用&foo0而不是bind(foo0,_1)有什么错?它已经是一元可调用的object@MSalters:这看起来确实是个骗局。使用
std::function
似乎可以实现一种神奇的转换,它可以实现OP想要的功能。否则,右边就没有天真地期望的语义了。@Jonathan:实际上是关于curry的。为了简单起见,我省略了更多的参数。是的,我同意uld也可以使用lambdas。@MSalters:Thanx作为参考。我认为你是对的。请随意将其标记为dublicate。@MSalters:I认为你是对的。我希望在回答此问题之前我已经跟随了你的链接。使用&foo0而不是bind(foo0,_1)有什么不对?它已经是一元可调用的object@MSalters:这看起来确实是个骗局。使用
std::function
似乎可以实现一种神奇的转换,它可以实现OP想要的功能。否则,右边就没有天真地期望的语义了。@Jonathan:实际上是关于curry的。为了简单起见,我省略了更多的参数。是的,我同意uld也可以使用lambdas。@MSalters:Thanx作为参考。我认为你是对的。请随意将其标记为dublicate。@MSalters:I认为你是对的。我希望在回答这个问题之前我已经跟随了你的链接。Boost.Bind提供了与你的
noeval(Bind-expr)
相当的
protect(Bind-expr)
。需要
eval(Bind-expr)
将使编写嵌套表达式变得更加困难,因为您确实希望将它们视为单个表达式,例如
bind(&Y::f,bind(&getY,bind(&getX,_1))
@JonathanWakely:有趣!我不知道
protect
。谢谢.Boost.bind提供了与您的
noeval相当的
protect(bind expr)
(bind-expr)
。需要
eval(bind-expr)
会使编写嵌套表达式变得更加困难,因为您确实希望它们被视为单个表达式,例如
bind(&Y::f,bind(&getY,bind(&getX,_1))
@JonathanWakely:有趣!我不知道
protect
。谢谢。