【问题标题】:Using SFINAE to check whether the class is same or is derived from another template class in C++98使用 SFINAE 检查类是否相同或从 C++98 中的另一个模板类派生
【发布时间】:2014-09-17 12:21:50
【问题描述】:

我正在尝试以更有效的方式读取 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&lt;bool&gt;,其中有两个专门用于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 和其他 3rd 方库。

【问题讨论】:

  • 您在此处发帖时将) 放在enum { value = sizeof(f((TSTLCollection*)0), int()) == sizeof(char) }; 中是错位还是实际代码中的错误? (并且修复了这个问题,当STLCollectionShouldBeResizedAndReadByIndex 用派生类实例化时,clang 和 g++ 都会报告歧义。)
  • 源代码中的一个错误。我正在调查...
  • 好的。当我修复错位的) 时,它实际上会引发一个警告,即ISO C++ 不允许这种构造,但我需要在这里编译value == true。好的,问题仍然存在:我应该如何以 ISO C++ 编译方式实现它?

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


【解决方案1】:

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

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

【讨论】:

  • 嗯...一切正常。 :) 在我看来,我在写这篇文章之前已经检查了这个变体。
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2015-08-25
  • 2012-10-04
  • 2017-05-04
  • 2021-04-13
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多