将函数作为类模板参数传递
Passing function as class template argument
在不知道函数类型的情况下,我使用下面的技术声明它的指针并初始化函数指针。
template<typename T>
struct Declare { typedef T Type; }; // for declaring any func ptr
void fun () {}
int main ()
{
Declare<fun>::Type pf = &fun; // can't use C++0x 'auto'
}
但是,它给出的编译错误为,error: expected a type, got ‘fun’
。尽管任何方法的类型在编译时都是已知的。将函数传递给类template
是否无效?
[注:用void (*)()
代替fun
也可以。但这不是我想要的。
像上面那样将函数传递给类模板是否无效?
完全正确,你混淆了类型参数和非类型参数。fun
是一个非类型参数,它是一个函数的地址,就像一个任意数字0x12345678
。typename T
是一个类型参数。您只能传递类型,如int
, MyClass
, double (*)(std::string)
, void (MyClass::*)()
。
你将不得不接受这样一个事实,你需要编译器支持这些东西,或者一些非常丑陋的技巧来推断类型。
如果你喜欢这种把戏,有Boost.Typeof
供像你这样的非c++ 0x程序员使用。它还为BOOST_AUTO
提供了auto
的替代品,但这只是编写BOOST_TYPEOF
的一种简短方式:
int hello(){ return 42; }
BOOST_AUTO(var1,hello()); // type of var1 == int
BOOST_TYPEOF(hello()) var2 = hello(); // same
问题?您需要为您拥有的每个用户定义类型帮助它。请看这个Ideone示例。
现在,大多数时候我认为你不需要Boost.Typeof。为什么?因为如果你使用一个函数,你当然需要知道签名,否则你怎么传递正确的参数呢?或者以正确的方式使用返回类型?
其他时间是在模板中使用的。如果你声明了一个像auto fptr = &func
这样的函数指针,那么你就知道func
的存在,也就是说你知道它的签名和类型。因为当你不知道func
存在时,你需要将它传递给你,最好是在模板中:
template<class FPtr>
void myfunc(FPtr otherfunc){
// use otherfunc
}
有了模板,你又有了函数类型的知识
像上面那样将函数传递到类模板中无效吗?
是的。因为,换句话说,您希望编译器推断出类模板的类型参数,这在c++中根本不可能。回想一下,fun
本身不是一个类型,它是一个类型为void (*)()
的值。但是你的类模板需要类型,而不是值。这就是为什么它不能工作。
只能对函数进行类型演绎,这意味着即使对类的构造函数也是如此。如果你写一个模板化的构造函数,然后你可以这样写:
Declare obj(&fun);
在这里,只要你在构造函数中,函数的类型是已知的,一旦你离开它,你就失去了信息。因此,您可能需要的是:定义一个类,例如AbstractFunctor
(可能是类模板),并从它派生定义另一个类,例如template<Fun fun> struct Functor
。然后,你可以创建一个Functor
的实例,它可以永远记住函数类型,并将该实例作为Declare
的成员数据存储在AbstractFunctor*
中。
但是我认为,即使这样,该类型也不能用作Declare::Type
或Declare::AbstractFunctor::Type
,因为类型存储在类的实例中;只有实例知道类型。因此,使用像A::Type
这样的语法获取类型是不可能的。您也不能使用语法instance.Type
获取类型。你所能做的就是:像调用函子一样,使用实例调用该函数。
编辑:
如果允许使用c++ 0x的其他特性(不包括auto),那么这个问题有一个简单的解决方案:
Declare<decltype(&fun)>::Type pf = &fun;
pf(); //call the function
Demo: http://ideone.com/
但是,你甚至不需要Declare
,因为你可以这样做:
decltype(&fun) pf = &fun;
pf(); //call the function
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 使用指向成员的指针将成员函数作为参数传递
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 如何传递带有通过引用传递的结构参数的函数?
- 如何在 c++ 中将函数作为参数传递?
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 为什么我不能将引用作为 std::async 的函数参数传递
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 将__device__ lambda 作为参数传递给 __global__ 函数
- 是否可以在不填充自己的参数的情况下将模板函数作为参数传递?
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 将函数作为参数传递以避免重复代码
- 如何在类(C )中作为参数传递函数