如何将 C++ 概念与 type_traits 一起使用?
How can I use C++ concepts with type_traits?
我想抽象类型接口,我很难在两种 C++ 概念和 type_traits 之间做出决定。考虑以下场景:
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(); }
};
Demo.
注意:requires(SizeHaving<T>)
应该在成员上完成,而不是 class 以允许 class.
的专业化
我想抽象类型接口,我很难在两种 C++ 概念和 type_traits 之间做出决定。考虑以下场景:
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(); }
};
Demo.
注意:requires(SizeHaving<T>)
应该在成员上完成,而不是 class 以允许 class.