C ++模板元编程静态类型检查

时间:2012-10-04 07:44:16

标签: c++ templates template-specialization

我无法找到问题的答案,所以我将其作为一个问题发布。我做了一个小例子来解释它:

enum STORAGE_TYPE
{
    CONTIGUOUS,
    NON_CONTIGUOUS
};

template <typename T, STORAGE_TYPE type=CONTIGUOUS>
class Data
{
    public:
        void a() { return 1; }
};

// partial type specialization
template <typename T>
class Data<T, NON_CONTIGUOUS>
{
    public:
        void b() { return 0; }
};

// this method should accept any Data including specializations…
template <typename T, STORAGE_TYPE type>
void func(Data<T, type> &d)
{
    /* How could I determine statically the STORAGE_TYPE? */
    #if .. ?? 
        d.a();
    #else
        d.b();
    #endif      
}


int main()
{
    Data<int> d1;
    Data<int, NON_CONTIGUOUS> d2;

    func(d1);
    func(d2);

    return 0;
}

请注意 (1)我不想要“func”的特化,因为这可以解决它,但我只想要一个通用方法“func”与内部静态“if”条件来执行代码。 (2),我更倾向于使用标准C ++(不是C ++ 0x或boost)的解决方案。

2 个答案:

答案 0 :(得分:5)

使用traits technique

template <typename T, STORAGE_TYPE type>
struct DataTraits {
  static void callFunction(Data<T, type> &d)
  {
    d.a();
  }
};

template <typename T>
struct DataTraits<T,NON_CONTIGUOUS> {
  static void callFunction(Data<T, NON_CONTIGUOUS> &d)
  {
    d.b();
  }
};


// this method should accept any Data including specializations…
template <typename T, STORAGE_TYPE type>
void func(Data<T, type> &d)
{
    /* How could I determine statically the STORAGE_TYPE? */
    DataTraits<T,type>::callFunction(d);
}

答案 1 :(得分:0)

关键是SFinae。您必须声明在存储类型上模板化的辅助类,并为其中一个提供定义定义。这样,如果存在特化,你就知道在编译时你有哪种存储类型(你提供了一个定义的存储类型),如果替换失败(这不是错误,SFINAE)你就是另一种情况。