我想抽象类型接口,并且很难在概念和type_traits的两种C ++方法之间做出选择。请考虑以下情形:
template <typename T>
int foo(const T& t) { return t.size() + t.size(); }
T
请提供该类型int T::size() const
。为了创建更好的错误消息,增加用户定义类型的客户端的可用性,并为客户提供明确定义的可接受类型必须具备的功能列表,可以引入以下概念:
template <typename T>
concept SizeHaving = requires(T t) {
t.size();
}
template <SizeHaving T>
int foo(const T& t) { return t.size() + t.size(); }
但是,如果一个客户类型原则上可以满足这个概念,但从技术上来说却不能(并且不能更改,因为它可能是第三方库的一部分)怎么办?一个type_trait可以帮助您:
struct Special {
int Dimension() const; // logically identical to size(), but a different name
};
template <typename T>
struct Type_traits {
static int size(const T& t) { return t.size(); }
};
template <> // user can provide the specialization for the custom type
struct Type_traits<Special> {
static int size(const Special& c) { return c.Dimension(); }
};
template <typename T>
int foo(const T& t) {
return Type_traits<T>::size(t) + Type_traits<T>::size(t);
}
如果的标准实现Type_trait
不适合自定义类型(并且未提供专业化设置),则会再次出现非常不幸的错误消息。如何将概念融入其中?我试过的是
template <typename T>
concept SizeHaving = requires(T t) {
Type_traits<T>::size(t);
}
但是无论哪种形式,无论是否Type_traits<T>::size()
可以显式实例化,表达式约束都将在技术上得到满足,从而使该概念毫无用处。我能做什么?
您可能还会限制自己的特征:
template <typename T>
concept SizeHaving = requires(const T& t) {
t.size(t);
};
template <typename T>
struct Type_traits
{
auto size(const T& t) requires(SizeHaving<T>) { return t.size(); }
};
template <typename T>
concept TraitSizeHaving = requires(T t) {
Type_traits<T>::size(t);
};
template <TraitSizeHaving T>
int foo(const T& t) {
return Type_traits<T>::size(t) + Type_traits<T>::size(t);
}
然后专门针对您的自定义类型:
struct Special {
int Dimension() const; // logically identical to size(), but a different name
};
template <> // user can provide the specialization for the custom type
struct Type_traits<Special> {
static int size(const Special& c) { return c.Dimension(); }
};
演示。
注意:requires(SizeHaving<T>)
应该在成员上进行,而不是在类上进行,以允许对该类进行专门化。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句