【问题标题】:Template Specialization for basic POD only仅适用于基本 POD 的模板专业化
【发布时间】:2012-01-14 17:30:55
【问题描述】:

模板专业化是否有一个微妙的技巧,以便我可以将一个专业化应用于basic POD(当我说基本 POD 时,我并不特别想要 struct POD(但我会接受)。

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

或者我是否必须为每个内置类型编写特化?

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";}
};

单元测试。

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


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

【问题讨论】:

  • 好吧,我很好奇 - 如果你想做的“东西”对于 POD 类型的实现并没有什么不同,该怎么办?
  • 我正在使用 boost::mpl。对于类对象,我需要注册一个操作类对象的操作(并为其所有成员注册操作)。对于普通的 POD 对象,我有一个更简单的操作,它将被注册以对对象执行操作。

标签: c++ templates template-specialization


【解决方案1】:

如果你真的只想要基本类型而不是用户定义的 POD 类型,那么以下应该可以工作:

#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
};

如果您还需要用户定义的 POD 类型,请使用 boost::is_pod&lt;&gt; 而不是 non_void_fundamental&lt;&gt;(如果您使用 C++11 并出于优化目的这样做,请改用 std::is_trivially_copyable&lt;&gt;)。

【讨论】:

    【解决方案2】:

    在 C++11 中,许多特性已添加到标准库中,并且大多数特性似乎特别针对有趣的专业化(尤其是按位操作)。

    您可能感兴趣的顶级特征是std::is_trivial,但还有很多其他特征:

    • std::is_trivially_default_constructible
    • std::is_trivially_copy_constructible
    • std::is_trivially_move_constructible
    • std::is_trivially_copyable(可通过memcpy复制)

    一般而言,该标准已尝试获得尽可能细粒度的特征,因此您无需依赖像 is_pod 这样广泛的假设,而是微调您的约束以匹配您的方法真正需要的内容。

    【讨论】:

      【解决方案3】:

      Boost 有boost::is_pod。这就是你要找的吗?

      (我从未使用过它,所以我不会因为尝试制定您的示例所需的精确代码而让自己感到尴尬。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-23
        • 1970-01-01
        • 2019-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-18
        • 1970-01-01
        相关资源
        最近更新 更多