C++ C++;绑定返回类型模板参数
我有以下代码:C++ C++;绑定返回类型模板参数,c++,function,templates,c++11,c++14,C++,Function,Templates,C++11,C++14,我有以下代码: #include <functional> template <typename T> class TD; // For displaying type void f(int, int, int) { } int main() { auto g = std::bind(f, std::placeholders::_1, 2, 2); TD<decltype(g)> td1; return 0; } 当然,不
#include <functional>
template <typename T>
class TD; // For displaying type
void f(int, int, int) { }
int main() {
auto g = std::bind(f, std::placeholders::_1, 2, 2);
TD<decltype(g)> td1;
return 0;
}
当然,不完整的类型错误除外。但是这个错误消息中让我好奇的是std::\u Bind
。我可以理解,std::_Bind
是一个代理类,它定义了操作符()
,使我们的目的成为可能。但是它的模板参数void(*(std::_Placeholder,int,int))(int,int,int)
让我大吃一惊!我应该如何解释它?它在用户土地代码中有用吗?如何使用此声明创建自己的类
void (*(std::_Placeholder<1>, int, int))(int, int, int)
现在,在(函数或模板的)参数声明中,可以省略名称,得到
void (int)
如果在函数声明的参数列表中使用,则相当于函数指针void(*)(int)
返回函数指针的函数声明如下:
void (*f(int))(int);
// ^ ^ <- this pair of parentheses changes
// the order in which the declaration is parsed.
// Without it, the return type would be `void*`
// and you'd get a syntax error
void(*f(int))(int);
// ^ ^
现在,在(函数或模板的)参数声明中,可以省略名称,得到
void (int)
如果在函数声明的参数列表中使用,则相当于函数指针void(*)(int)
返回函数指针的函数声明如下:
void (*f(int))(int);
// ^ ^ <- this pair of parentheses changes
// the order in which the declaration is parsed.
// Without it, the return type would be `void*`
// and you'd get a syntax error
void(*f(int))(int);
//C++11的出现使得定义函数指针变得更加容易:
函数的实例可以存储、复制和调用任何可调用的目标函数——函数、lambda表达式、绑定表达式或其他函数对象,以及指向成员函数的指针和指向数据成员的指针
例如,假设您需要在其中一个函数中引入一个指向stringfoo(int-param){return to_string(param);}
的函数指针。在C++11之前,您的函数需要如下所示:
void bar(string (*func)(int)) { cout << func(13) << endl; }
它能够接受传统函数指针和bind
函子。此外,它还可以处理lambda,因此您可以这样做:bar3([](int-param){return to_-string(param);})代码>
我已经创建了一个,这样您就可以使用它了。函数
对象的一些好处很明显。C++11标志着它的出现,使得定义函数指针变得更加容易:
函数的实例可以存储、复制和调用任何可调用的目标函数——函数、lambda表达式、绑定表达式或其他函数对象,以及指向成员函数的指针和指向数据成员的指针
例如,假设您需要在其中一个函数中引入一个指向stringfoo(int-param){return to_string(param);}
的函数指针。在C++11之前,您的函数需要如下所示:
void bar(string (*func)(int)) { cout << func(13) << endl; }
它能够接受传统函数指针和bind
函子。此外,它还可以处理lambda,因此您可以这样做:bar3([](int-param){return to_-string(param);})代码>
我创建了一个对象,您可以使用它,希望函数
对象的好处很明显。Woow!我怎么忘了应用那个简单的类型声明了!:)现在只剩下一件事了。如果您能详细说明“std::bind”是如何使用它的,那就太好了!:)@jnbrq CanberkSönmez如果您正在考虑使用\u占位符
,请知道它是非标准的。您将使用仅在此特定版本的编译器中定义的类型。它甚至不能保证在未来版本的编译器中工作。哇!我怎么忘了应用那个简单的类型声明了!:)现在只剩下一件事了。如果您能详细说明“std::bind”是如何使用它的,那就太好了!:)@jnbrq CanberkSönmez如果您正在考虑使用\u占位符
,请知道它是非标准的。您将使用仅在此特定版本的编译器中定义的类型。它甚至不能保证在编译器的未来版本中工作。实际上,这并不完全是我需要知道的。我的问题主要是void(*(std:_Placeholder,int,int))(int,int,int)
的意思和它可以在哪里使用。@jnbrq CanberkSönmez实际上,这确实解决了如何使用bind
的返回,只是没有具体说明为什么应该使用函数
而不是\u bind
我编辑了答案来解释这一点。tldr:bind
返回的类型是特定于实现的。您必须使用函数
对象来接受它。除非您确实需要类型擦除,否则最好使用函数模板并按原样接受函数对象。@T.C.我觉得您在这里给了我一条有价值的信息,但我不明白。你能澄清一下你说的是什么吗更好的方法是?template void bar4(F func){cout好吧,实际上并不完全是我需要知道的。我的问题主要是void(*(std:_Placeholder,int,int))(int,int,int)
的意思和使用位置。@jnbrq CanberkSönmez实际上,这确实解决了如何使用bind
的返回,只是没有具体说明为什么应该使用函数而不是\u bind
我编辑了答案来解释这一点。tldr:bind
返回的类型是特定于实现的必须使用函数
对象来接受它。除非您确实需要类型擦除,否则最好使用函数模板并按原样接受函数对象。@T.C.我觉得您在这里给了我一条有价值的信息,但我不明白。您能澄清一下您的意思吗?更好的方法是使用tem板空棒4(F func){cout