指向成员函数的指针的模板参数推导
template argument deduction for pointer to member function?
我正在尝试构建一个静态绑定的委托类,在编译时绑定成员函数,从而帮助优化。
我有以下代码,它正是我想要的工作方式:
#include <iostream>
namespace thr {
template<typename T, T func>
struct delegate;
template<typename R,
typename C,
typename... A,
R (C::* mem_fun)(A...)>
struct delegate<R(C::*)(A...), mem_fun>
{
delegate(C* obj_)
: _obj(obj_)
{}
R operator()(A... a)
{
return (_obj->*mem_fun)(a...);
}
private:
C* _obj;
};
} // namespace thr
struct foo
{
double bar(int i, int j)
{
return (double)i / (double)j;
}
};
int main()
{
foo f;
typedef thr::delegate<decltype(&foo::bar), &foo::bar> cb;
cb c(&f);
std::cout << c(4, 3);
return 0;
}
然而,用法并不是很优雅:
thr::delegate<decltype(&foo::bar), &foo::bar>
我想使用一个函数模板,它推导模板参数并返回一个委托实例;大致如下(此代码不编译):
template<typename C, typename T, T func>
thr::delegate<T, func> bind(T func, C* obj)
{
return thr::delegate<decltype(func), func>(obj);
}
这将允许更优雅的语法:
auto cb = bind(&foo::bar, &f);
是否可以在函数模板中推导出非类型参数?
我努力实现的目标可能实现吗?
std::函数有帮助吗?http://www2.research.att.com/~bs/C++0xFAQ.html#std函数您的示例看起来非常接近。
我认为编译器提供的STL做了一些非常可怕的事情来使其顺利工作。在放弃之前,你可能想看看这个例子。
编辑:我出去尝试了你想要完成的事情。我的结论是一个编译错误:
- 绑定(委托)的返回类型必须命名指向成员的指针,因为这是您自己的要求
bind
应该接受指向优雅成员的指针的名称(即您的要求)- 编译器要求您不要用函数参数遮蔽模板参数,也不要在参数和返回类型中同时使用名称
因此,您的一项要求必须取消。
编辑2:我冒昧地更改了您的委托,使绑定工作如您所愿。绑定可能不是你的首要任务。
#include <iostream>
namespace thr {
template<typename C,typename R,typename... A>
struct delegate
{
private:
C* _obj;
R(C::*_f)(A...);
public:
delegate(C* obj_,R(C::*f)(A...))
: _obj(obj_),_f(f)
{}
R operator()(A... a)
{
return (_obj->*_f)(a...);
}
};
} // namespace thr
template<class C,typename R,typename... A> thr::delegate<C,R,A...> bind(R(C::*f)(A...),C* obj){
return thr::delegate<C,R,A...>(obj,f);
}
struct foo
{
double bar(int i, int j)
{
return (double)i / (double)j;
}
};
int main()
{
foo f;
auto c = bind(&foo::bar, &f);
std::cout << c(4, 6);
return 0;
}
可以推导出函数签名中类型以外的其他实体,但函数参数本身不能用作模板参数。
给定:
template <size_t I> struct Integral { static size_t const value = I; };
你可以有:
template <size_t N>
Integral<N> foo(char const (&)[N]);
但你不能有:
Integral<N> bar(size_t N);
在前一种情况下,作为数组大小的N
是参数类型的一部分,在后一种情况中,N
是参数本身。可以注意到,在前一种情况下,N
出现在类型签名的模板参数列表中。
因此,如果您确实想要的是可能的,则成员指针值必须作为函数签名的模板参数列表的一部分出现。
使用constexpr
可能会有一个节省的宽限期,它可以将规则值转换为模板参数的常数:
constexpr size_t fib(size_t N) { return N <= 1 ? 1 : fib(N-1) + fib(N-2); }
Integral<fib(4)> works;
但我不够精明,不能走那条路。。。
然而,我有一个简单的问题:为什么你认为这会加快速度?编译器非常擅长常量传播和内联,当他们可以在编译时评估变量的动态类型时,就可以内联对虚拟函数的调用。你确定这件事值得大汗淋漓吗?
相关文章:
- 使用指向成员的指针将成员函数作为参数传递
- 如何使用Visual Studio 2017在C++中为参数化对象数组使用唯一指针
- 修改函数中的指针(将另一个指针作为参数传递)
- Clang bug?使用指针作为模板参数
- MSVC将仅移动结构参数解释为指针
- 非类型指针和引用模板参数,以及在编译时如何/为什么解析它们.c++
- 如何使用非类型模板参数传入指向数组的指针
- 将成员函数指针作为参数传递给模板方法
- 匹配函数指针作为模板参数?
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 通过智能指针和转换对基本模板参数进行模板推导
- 为函数定义符号不明确的指针参数
- 使用引用与指针将数组作为参数传递
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- C++ - 声明指向返回任何类型并获取任意数量参数的函数的指针
- 将函数参数完美转发到函数指针:按值传递呢?
- 保留函数指针模板参数
- 如何构造一个以可变参数指针函数作为成员的类?
- 指向对象的非类型模板参数指针
- c++ 使用 *& as 参数(指针乐趣,三级树方法)