将函数作为类模板参数传递
在不知道函数类型的情况下,我使用以下技术声明其指针并初始化函数指针。
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'
}
但是,它会给出编译错误,错误:需要一个类型,得到'fun'
。尽管任何方法的类型在编译时都是已知的。 如上所述将函数传递到类 template
中是否无效?
[注意:将 fun
替换为 void (*)()工作正常。但这不是我们想要的。]
Without knowing a function's type, I am declaring its pointer with below technique and initializing a function pointer.
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'
}
However, it gives compile error as, error: expected a type, got ‘fun’
. Though the type of any method is known at compile time. Is it invalid to pass a function into a class template
as above ?
[Note: replacing fun
with void (*)()
works fine. But that's not what want.]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
完全是的,您混淆了类型参数和非类型参数。
fun
是一个非类型参数,它是一个函数的地址,就像一个任意数0x12345678
。typename T
是一个type 参数。您只能传递类型,例如int
、MyClass
、double (*)(std::string)
、void (MyClass ::*)()
.您必须接受这样一个事实:您需要编译器支持这些东西,或者需要一些非常丑陋的技巧来推断类型。
如果您想上当,这里有
Boost。 Typeof
适用于像您这样的非 C++0x 编码员。它还为auto
提供了BOOST_AUTO
的替代品,但这只是编写BOOST_TYPEOF
的一种简短方法:有问题吗?您需要为您拥有的每个用户定义类型提供帮助。请参阅此 Ideone 示例。
现在,大多数时候我认为您不需要 Boost.Typeof。为什么?因为如果你使用一个函数,你当然需要知道签名,否则你将如何传递正确的参数?或者以正确的方式使用返回类型?
其他时候都是在模板中使用。如果您声明一个像 auto fptr = &func 之类的函数指针,那么您就知道 func 存在,也就是说您知道它的签名和类型。因为当您不知道
func
存在时,您无论如何都需要将其传递给您,最好是在模板中:并且通过模板,您可以再次了解该函数类型。
Totally yes, you're mixing up type and non-type parameters.
fun
is a non-type argument, it's an address of a function, like an arbitary number0x12345678
.typename T
is a type parameter. You can only pass it types, likeint
,MyClass
,double (*)(std::string)
,void (MyClass::*)()
.You'll just have to life with the fact, that you need compiler support for that stuff or some really ugly trickery to deduce the type.
If you're in for the trickery, there's
Boost.Typeof
for non-C++0x coder like you. It also provides a stand-in forauto
withBOOST_AUTO
, but that is only a short way for writingBOOST_TYPEOF
:The problem? You need to help it for every user-defined type you have. See this Ideone example.
Now, most of the time I don't think you need Boost.Typeof. Why? Because if you use a function, you of course need to know the signature, how would you pass the correct arguments otherwise? Or use the return type in a correct way?
The other times are the usage in templates anyways. If you declare a function pointer like
auto fptr = &func
, then you have the knowledge, thatfunc
exists, aka you know its signature and type. For when you don't know thatfunc
exists, you need it passed to you anyways, preferably in a template:And with a template you have the knowledge of that functions type again.
是的。换句话说,因为您希望编译器推断出类模板的 type 参数,这在 C++ 中根本不可能。回想一下,
fun
本身不是一个类型,它是一个void (*)()
类型的值。但是您的类模板需要类型,而不是值。这就是为什么它行不通。类型推导仅适用于函数,这意味着即使使用类的构造函数也是如此。因此,如果您编写一个模板化构造函数,那么您可以这样写:
这里,只要您在构造函数中,函数的类型就已知,一旦您从中存在,您就会丢失该信息。所以您可能需要的是:定义一个类,例如
AbstractFunctor
(可能是类模板),并从它派生定义另一个类,例如template;结构函子
。然后你可以创建一个永远记住函数类型的Functor
实例,并将该实例作为Declare
的成员数据存储在AbstractFunctor*
中。但我认为,即使这样,类型也不能用作
Declare::Type
或Declare::AbstractFunctor::Type
,仅仅因为 type< /em> 存储在类的实例中;只有实例知道类型。因此,使用A::Type
之类的语法获取类型是不可能的。并且您也无法使用语法instance.Type
获取类型。您所能做的就是:使用实例调用函数,就像函子一样。编辑:
如果您被允许使用 C++0x 的其他功能(不包括自动),那么问题有一个简单的解决方案:
演示: http://ideone.com/
但是,您甚至不需要
Declare
,因为您可以这样做:Yes. Because what you, in other words, want the compiler to deduce the type parameter for the class template, which simply not possible in C++. Recall that
fun
itself isn't a type, its a value of typevoid (*)()
. But your class template expects type, not value. That's why it wouldn't work.Type deduction is possible with functions only, that means even with the constructor of class. So if you write a templated constructor, and then you can write this:
Here the type of the function is known as long as you're in constructor, once you exist from it, you lost the information. So what you probably need is : define a class, say,
AbstractFunctor
(possibly class template) and derived from it defining an another class saytemplate<Fun fun> struct Functor
. Then you can create an instance ofFunctor
which can remember the function type forever, and store the instance inAbstractFunctor*
as a member data ofDeclare
.But I think, even in this way, the type cannot be used as
Declare::Type
orDeclare::AbstractFunctor::Type
, simply because the type is stored in an instance of the class; only the instance knows the type. So the getting type using syntax likeA::Type
is out of the question. And you cannot get type using syntaxinstance.Type
either. All you can do is : call the function, using the instance, like a functor.EDIT:
If you're allowed to use C++0x's other features (excluding auto), then the problem has a trivial solution:
Demo : http://ideone.com/
But then, you don't need even
Declare
, as you can do this instead: