C++ 作为模板参数传递的函数指针
我阅读了一些代码,发现有一个例子,函数指针(地址,而不是类型)被传递给模板参数C++ 作为模板参数传递的函数指针,c++,templates,function-pointers,C++,Templates,Function Pointers,我阅读了一些代码,发现有一个例子,函数指针(地址,而不是类型)被传递给模板参数 // connects a free function registry.on_construct<position>().connect<&my_free_function>(); // connects a member function registry.on_construct<position>().connect<&my_class::memb
// connects a free function
registry.on_construct<position>().connect<&my_free_function>();
// connects a member function
registry.on_construct<position>().connect<&my_class::member>(instance);
//连接一个自由函数
registry.on_construct().connect();
//连接成员函数
registry.on_construct().connect(实例);
我以前从未见过这种情况。因为我认为只有类型和整数可以传递给模板参数,所以我认为您需要这样做:
connect<decltype(&my_free_function)>(&my_free_function);
void my_free_function() { std::cout << "free function called\n"; }
template <auto Function>
void templatedFunc()
{
std::cout << typeid(Function).name();
// The type of Function according to type_info is void (__cdelc*)(void)
Function(); // This means we call Function function pointer with no dynamic/runtime binding?
}
int main()
{
templatedFunc<&my_free_function>();
}
connect(&my\u free\u函数);
我花了很长时间才意识到这可能是一种静态绑定和调用函数指针的方法?这是我以前从未见过的。被调用的代码如下所示:
connect<decltype(&my_free_function)>(&my_free_function);
void my_free_function() { std::cout << "free function called\n"; }
template <auto Function>
void templatedFunc()
{
std::cout << typeid(Function).name();
// The type of Function according to type_info is void (__cdelc*)(void)
Function(); // This means we call Function function pointer with no dynamic/runtime binding?
}
int main()
{
templatedFunc<&my_free_function>();
}
void my_free_函数(){std::cout
这就是我认为它正在做的,即,函数指针的静态绑定调用吗
是的,这正是您认为它正在做的事情。它将参数绑定为类型本身的一部分,这样就不需要将其作为运行时参数传递
模板参数是否需要自动才能工作
不--auto
只是使它更灵活,以便它可以接受任何可调用对象的实例--无论是函数指针、通用lambda,甚至是函子对象
具体来说,对于函数指针,也可以这样写:
模板
类信号
{
...
模板
自动连接()->void;
...
};
但是,请注意,在执行此操作时,它会强制执行精确的签名--这不是很有表现力。例如,您不能执行以下操作:
float添加(float,float);
自动信号=信号{};
sig.connect();//错误:无法将模板参数的float(*)(float,float)转换为double(*)(double,double)
使用auto
,它允许您推断参数类型——并允许这样的模板支持隐式转换——如果正确使用,这种转换实际上非常强大。这有点像std::function
如何绑定具有类似但不完全相同参数的函数,并使其仍然工作——除了都是静态完成的,而不是动态完成的
如果您想知道为什么在运行时参数上使用此模式,那是因为在构建回调系统时,它启用了一种非常简单的类型擦除形式。保持函数的静态状态可以让编译器比std::function
更好地内联代码,而且它的内存占用也更小
通过使用functiontemplate
s,实例化的函数模板的签名永远不会改变——这允许以一种同构的方式存储该模板以备将来使用:
模板
类委托{
...
//每次将扩展为相同指针类型的函数
模板。讨论auto
参数,并将执行时间与原始函数指针进行比较。template void templatedFunc();
也可以,但更为有限。“因为我认为只有类型和整数才能传递到模板参数”-“非类型”case不仅仅包括整数;casestd::函数也可以包含任何类型的可调用函数,但它们之间的函数签名需要相同,对吗?几乎如此。std::function
实际上允许对参数和输出进行隐式转换。您可以将std::function
绑定到sh类型的函数ort(short)
它只是为您进行升级。类似地,std::function
将在绑定返回某个内容的函数时放弃输出。使用auto
非类型模板参数,您基本上可以编写完成相同内容的内容—仅静态编写。