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