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

Using SFINAE to check whether the class is same or is derived from another template class in C++98

本文关键字:C++98 派生 另一个 检查 SFINAE 是否 使用      更新时间:2023-10-16

我正在尝试读取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没有value == true。出了什么问题,我应该如何解决?

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

不确定我是否清楚地理解您的意图:

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

现场演示