说我有一个班级X1
,它来自Y
和另一个班级X2
。 Y
和X2
具有特定的特征Z_trait
。
现在我有一个模板函数,我想检查参数是否具有特定的特征。
这就是我所拥有的:
#include<type_traits>
template <typename T>
struct Y {};
struct X1 : Y<int> {};
struct X2 {};
struct Z_trait {};
template <typename Container>
struct has_trait;
template <>
struct has_trait<X2>
{
typedef Z_trait type;
};
template <typename T>
struct has_trait<Y<T>>
{
typedef Z_trait type;
};
template <typename Container>
void fn(Container& container)
{
static_assert(std::is_same<typename has_trait<Container>::type, Z_trait>::value
, "must have Z_trait");
Container* x = &container;
++x;
}
int main()
{
X1 x1;
X2 x2;
Y<char> y;
fn(x1);
fn(x2);
fn(y);
return 0;
}
演示
我想要它,以便has_trait
为所有三种类型提供Z_trait
。我该怎么做?有没有办法迭代所有基类,还是有一些更简单的方法来测试特征?
注意我没有使用使用模板。原因是VS2013并没有完全支持这一点。
哦,仅供参考,我不想改变X1
,X2
或Y
的实施。
答案 0 :(得分:1)
您希望为后代专门设置has_trait<>
,而不仅仅是基础:
#include<type_traits>
struct Y {};
struct X1 : Y {};
struct X2 {};
struct Z_trait {};
template <typename Container, typename = void>
struct has_trait;
template <typename T>
struct has_trait<T, typename std::enable_if< std::is_base_of<X2, T>::value >::type >
{
typedef Z_trait type;
};
template <typename T>
struct has_trait<T, typename std::enable_if< std::is_base_of<Y, T>::value >::type >
{
typedef Z_trait type;
};
template <typename Container>
void fn(Container& container)
{
static_assert(std::is_same<typename has_trait<Container>::type, Z_trait>::value
, "must have Z_trait");
Container* x = &container;
++x;
}
int main()
{
X1 x1;
X2 x2;
Y y;
fn(x1);
fn(x2);
fn(y);
return 0;
}
此外,您可能会考虑static constexpr const bool has_z_trait = true;
或static bool hasTrait(const ZTrait&) { return true; }
,这会使静态断言变得更简单。