使用SFINAE检查类是否相同或是否从C ++ 98中的另一个模板类派生

时间:2014-09-17 12:21:50

标签: c++ templates stl sfinae c++98

我正在尝试阅读STL集合,并以更有效的方式为那些使用resize()operator[]()方法而不是std::insert_iterator方法的集合分配内存。我还定义了几个看起来像STL集合的非STL集合,但它们不是(某些函数可能没有实现,例如insert(iterator, const_reference),我根本不能使用std::insert_iterator)。

我编写了以下函数来读取集合:

template<typename TSTLCollection> 
void ReadCollection(TSTLCollection* pCollection)
{
    ReadingCollectionFunctorClass<
            STLCollectionShouldBeResizedAndReadByIndex<TSTLCollection>::value
        >(pCollection);
}

我有一个仿函数模板ReadingCollectionFunctorClass<bool>,其中包含两个truefalse值的特化。它们都实现了模板成员函数

template<typename TSTLCollection>
void operator()(TSTLCollection*);

接下来我想要检查必须调用哪些特化。为了存档这个我写了这个类:

template<typename TSTLCollection>
struct STLCollectionShouldBeResizedAndReadByIndex
{
private:
    template<typename TItem>
    static char f(NonSTLCollection<TItem>* pCollection, int);
    template<typename TItem>
    static char f(std::basic_string<TItem>* pCollection, int);
    template<typename TItem>
    static char f(std::vector<TItem>* pCollection, int);
    template<typename TCollection>
    static long f(TCollection* pCollection, ...);
public:
    enum { value = sizeof(f((TSTLCollection*)0, int())) == sizeof(char) };
};

如果我致电ReadCollection(pStlCollection),一切都很有效,但问题是,如果我致电ReadCollection(pClassDerivedFromStlCollection),它就无法运作:STLCollectionShouldBeResizedAndReadByIndex没有{{1}对于派生类。有什么问题,我应该如何解决这个问题?

我不能使用C ++ 11或C ++ 14功能,只能使用C ++ 98。我也不能使用boost和其他第三方库。

1 个答案:

答案 0 :(得分:3)

不确定我是否明白了你的意图:

template <typename TSTLCollection>
struct STLCollectionShouldBeResizedAndReadByIndex
{
private:
    template <typename TItem>    
    static char f(NonSTLCollection<TItem>* pCollection);

    template <typename TItem>    
    static char f(std::basic_string<TItem>* pCollection);

    template <typename TItem>
    static char f(std::vector<TItem>* pCollection);

    static long f(...);

public:
    enum { value = sizeof(f((TSTLCollection*)0)) == sizeof(char) };
};

LIVE DEMO