元编程:如何从模板的结构和类中识别POD类型? [英] Metaprogramming: How do I discern POD types from structs and classes in templates?

查看:93
本文介绍了元编程:如何从模板的结构和类中识别POD类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要实现一个模板函数,该模板函数对POD类型(双精度,整型,字符型等)具有不同的行为,而不是可以具有构造函数和析构函数的实际结构或类类型.

我可以通过为所有类型提供通用函数来解决此问题:

I want to implement a template function that has different behaviour for POD types (double, int, char, etc.) as opposed to actual structs or class types that can have constructors and destructors.

I could solve this by providing a generic function for all types:

template <class T> void alloc(T*& p, std::size_t size) {
   p = reinterpret_cast<T*> ( malloc(size*sizeof(T)) );
   new (p) T[size];
}

,然后是所有POD类型的专业化:

and then specialisations for all POD types:

template <> void alloc(double*& p, std::size_t size) {
   p = reinterpret_cast<double*> ( malloc(size*sizeof(double)) );
}


但是,如果可以避免的话,我宁愿不重复复制或粘贴相同的代码6至8次.

那么,有没有更好的方法来区分POD类型和其他类型,而这又不会迫使我再次复制专业化知识?

在您问之前,不可以,不能选择new和delete.我计划稍后在这里植入我自己的内存管理器. (这将意味着更多的规范化!)


邮编:
为了使那些对我上面概述的问题有一些简单答案的人想知道是否需要这样做的原因:

实际问题比上面的示例更复杂,包括
-通过多个函数调用传递模板参数的类;因此,即使编译器可以,在调用分配器的那一刻我也不知道实际的类型
-其他分配器,这些分配器除其他功能外,还可以传递初始化程序值
-某些类或什至POD类型(例如TCHAR)的专业化,在分配或释放时需要进行特殊处理

第一个问题是最严格的问题.如果找到解决方案,我可以将第二个工作缩减为现在可以做的工作,然后再扩展.鉴于这个问题,最后一个问题目前似乎还不是问题,但我尚未检查所有案例.


However, I''d rather not copy/paste the same code all over again 6-8 times if I can avoid it.

So is there a better way to distinguish between POD types and others that doesn''t force me to copy specializations all over again?

And before you ask, no, new and delete are not an option. I plan to implant my own memory manager here later. (and that will mean even more specalizations!)


P.S.:
For the sake of those wondering about the need for this in the view of some simple answers to the problem I outlined above:

The actual problems are more convoluted than the above example, including
- a class that passes on the template parameter through several function calls; therefore, even though the compiler does, I do not know the actual type at the point I call the allocator
- additional allocators that, among other things, provide the ability to pass an initializer value
- specializations for certain classes or even POD types (such as TCHAR) that need a particular treatment upon allocation or deallocation

The first issue is the most restricting one. The second I could cut down to whatever I can make work for now and expand later, if I find a solution. The last issue doesn''t currently seem to be a problem in light of the question, but I haven''t checked all cases yet.

推荐答案

我不知道没有看到为什么您需要以不同的方式处理POD类型.他们的构造函数"是无操作的,您泛型的函数将扩展为对POD类型的malloc调用.就像您的第二个专业版本一样.
I don''t see why you would need to handle POD types differently. Their ''constructors'' are no-ops, and your generic version of the function will expand to just a malloc call for POD types. Just like your second specialized version.


我只看到一种可能性:使用宏.但是您最终可能会得到非常脏的代码...

顺便说一句,我不太了解您的需求.模板函数应该针对不同类型执行相同的操作.如果您希望不同类型的行为不同,那么为什么要使用模板?

您可能可以编写2个模板函数:一个用于类类型,一个用于"POD"类型.
I see only one possibilty: using macros. But you will probably end up with a very dirty code...

By the way, I don''t really understand your need. Template functions are supposed to do the same things for different types. If you want a different behaviour for differents types, then why use templates?

You could maybe write 2 template functions: one for class types, one for "POD" types.


您可以使用SFINAE原理从编译时的重载集中排除一个函数,例如此功能模板的实例:

You can exclude a function from the overload set at compile using the SFINAE principle, e.g. an instantiation of this function template:

template< class T >
void alloc(T*& p, std::size_t s, 
 typename std::enable_if< std::is_pod< T >::value, void* >::type = 0)
{
 // do pod work here
}



仅当std::is_pod< T >::value在编译时为true时,才被视为有效的重载.
干杯,

保罗



would only be considered a valid overload if std::is_pod< T >::value is true at compile time.

Cheers,

Paul


这篇关于元编程:如何从模板的结构和类中识别POD类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆