从 C++ 中的模板 class 继承,枚举作为模板参数
Inheriting from a template class in c++ with enum as template parameter
我有一些相同的 classes 包含带有命名常量的枚举(如下面的部分)和常量的文本描述(如部分但字符串)。每个来源 class 看起来像下面两个 classes 的联合(不是 c++ 联合 :-))。想要删除代码冗余并暂时得到这样的东西:
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 的标准)所以编译器给出错误(如预期的那样)。我不想从 Child 移出 Parts,因为它在意识形态上是 Child 的一部分。有什么美容方法可以解决这种情况吗?
I don't want move out Parts from Child because it part of Child ideologically
这并不意味着它必须存储在 Child
class 本身内部。
无论是否有 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
};
Child
和 Parts
之间的联系是通过模板特化(在 C++98 中也可用)建立的:Child
类型充当正确特化的关键,其中包含正确的 Parts
类型。
我有一些相同的 classes 包含带有命名常量的枚举(如下面的部分)和常量的文本描述(如部分但字符串)。每个来源 class 看起来像下面两个 classes 的联合(不是 c++ 联合 :-))。想要删除代码冗余并暂时得到这样的东西:
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 的标准)所以编译器给出错误(如预期的那样)。我不想从 Child 移出 Parts,因为它在意识形态上是 Child 的一部分。有什么美容方法可以解决这种情况吗?
I don't want move out Parts from Child because it part of Child ideologically
这并不意味着它必须存储在 Child
class 本身内部。
无论是否有 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
};
Child
和 Parts
之间的联系是通过模板特化(在 C++98 中也可用)建立的:Child
类型充当正确特化的关键,其中包含正确的 Parts
类型。