使用枚举作为模板参数从c ++中的模板类继承

时间:2017-12-12 14:43:50

标签: c++ inheritance refactoring c++98

我有一些相等的类,包含带有命名常量的枚举(如下面的部分)和常量的文本描述(比如部分但是字符串)。每个源类看起来像下面两个类的union(不是c ++ union :-))。想要删除代码冗余并暂时得到类似的东西:

template<class T> class SomeBaseClass
{
public:
    std::string toString()
    {
        uint32_t pairsNum = pairs.size();
        for (uint32_t i = 0; i < pairsNum; i++)
            if (pairs[i].first == name) {
                return pairs[i].second;
            }
        // exception will be here
        return std::string("");
    }
    void fromString(std::string name)
    {
        uint32_t pairsNum = pairs.size();
        for (uint32_t i = 0; i < pairsNum; i++)
            if (pairs[i].second == name) {
                this->name = pairs[i].first;
                return;
            }
        throw std::invalid_argument(name);
    }
    T get()
    {
        return name;
    }
    void set(T name)
    {
        this->name = name;
    }
private:
    T name;
    std::vector<std::pair<T, std::string> > pairs;
};

class Child: public SomeBaseClass<Child::Parts>
{
public:
    enum Parts { head, rightLeg, leftLeg, rightHand, leftHand, body };
    Child()
    { 
        /* filling SomeBaseClass::pairs by values will be here */
    }
};

但是Child :: Parts是嵌套类型而不是c ++ 98的用户类型(对于这个程序不能使用超过c ++ 98标准),因此编译器会出错(如预期的那样)。我不想从儿童搬出部分,因为它是儿童意识形态的一部分。有没有美容方式来解决这种情况?

1 个答案:

答案 0 :(得分:2)

  

我不想把孩子的部分搬出去,因为它是儿童意识形态的一部分

这并不意味着它必须存储在Child类本身内。 你想要完成的是不可能的,不管是C ++ 98。常见的方法是使用 traits

template <typename>
struct Child_traits;

class Child;

template <>
struct Child_traits<Child> {
   enum Parts { head, rightLeg, leftLeg, rightHand, leftHand, body };
};

template <typename T>
class SomeBaseClass {
   typedef typename Child_traits<T>::Parts Parts;

   // use Parts type
};

class Child : public SomeBaseClass<Child> { 
    typedef Child_traits<Child>::Parts Parts; // get the parts type to the child
};

ChildParts之间的绑定是通过模板特化(在C ++ 98中也可用)建立的:Child类型作为包含正确的正确特化的键Parts类型。