Template Specialization for basic POD only

落爺英雄遲暮 提交于 2019-12-07 02:35:44

问题


Is there a subtle trick for template specialization so that I can apply one specialization to basic POD (when I say basic POD I don't particularly want struct POD (but I will take that)).

template<typename T>
struct DoStuff
{
    void operator()() { std::cout << "Generic\n";}
};
template<>
struct DoStuff</*SOme Magic*/>
{
    void operator()() { std::cout << "POD Type\n";}
};

Or do I have to write specializations for each of the built in types?

template<typename T>
struct DoStuff
{
    void operator()() { std::cout << "Generic\n";}
};


// Repeat the following template for each of
// unsigned long long, unsigned long, unsigned int, unsigned short, unsigned char
//          long long,          long,          int,          short, signed   char
// long double, double, float, bool
// Did I forget anything?
//
// Is char covered by unsigned/signed char or do I need a specialization for that?
template<>  
struct DoStuff<int>
{
    void operator()() { std::cout << "POD Type\n";}
};

Unit Test.

int main()
{
    DoStuff<int>           intStuff;
    intStuff();            // Print POD Type


    DoStuff<std::string>   strStuff;
    strStuff();            // Print Generic
}

回答1:


If you really want only fundamental types and not user-defined POD types then the following should work:

#include <iostream>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_same.hpp>

template<typename T>
struct non_void_fundamental : boost::integral_constant<
    bool,
    boost::is_fundamental<T>::value && !boost::is_same<T, void>::value
>
{ };

template<typename T, bool Enable = non_void_fundamental<T>::value>
struct DoStuff
{
    void operator ()() { std::cout << "Generic\n"; } const
};

template<>
struct DoStuff<T, true>
{
    void operator ()() { std::cout << "POD Type\n"; } const
};

If you also want user-defined POD types, then use boost::is_pod<> instead of non_void_fundamental<> (and if you're using C++11 and doing this for optimization purposes, use std::is_trivially_copyable<> instead).




回答2:


In C++11, many traits have been added to the standard library, and most seem particularly aimed toward interesting specializations (and notably bitwise manipulations).

The top-level trait you could be interested in is std::is_trivial, however there are many others:

  • std::is_trivially_default_constructible
  • std::is_trivially_copy_constructible
  • std::is_trivially_move_constructible
  • std::is_trivially_copyable (can be copied via memcpy)

In general, the Standard has tried to get as finer grained traits as possible so you need not rely on such broad assumptions as is_pod but instead fine-tune your constraints to match what your methods really need.




回答3:


Boost has boost::is_pod. Is that what you're looking for?

(I've never used it, so I won't embarrass myself by trying to formulate the precise code that you require for your example.)



来源:https://stackoverflow.com/questions/8863965/template-specialization-for-basic-pod-only

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!