我希望有一个concept
,需要一个任意向量作为返回类型:
template<typename T>
concept HasVector = requires (T t) {
{ T.vec() } -> std::same_as<std::vector<int>>; //works
{ T.vec() } -> std::same_as<std::vector<foo>>; //want to put something arbitrary in here
}
这样我们就得到了如下的结果:
class A {
std::vector<int> vec() { /* ... */}
}
class B {
std::vector<double> vec() { /* ... */}
}
static_assert(HasVector<A>);
static_assert(HasVector<B>);
此外,如果需要一个值类型满足其他概念的向量作为返回类型,那就更好了。
template<typename T>
concept Arithmetic = // as in the standard
template<typename T>
concept HasArithmeticVector = requires (T t ) {
{ T. vec() } -> std::same_as<std::vector<Arithmetic>>;
有没有这样一种方法把它放在概念的名称中呢?
4条答案
按热度按时间v64noz0r1#
我们首先编写一个变量模板来检查一个类型是否专用于一个模板:
我们可以把它变成一个概念:
然后我们可以用它来实现另一个概念:
如果您想做进一步的检查,那只是添加更多的需求。
nnsrf1az2#
Demo.
wvmv3b1j3#
虽然我确实喜欢巴里的方法,但我不喜欢该解决方案强加的比实际情况更通用(它不能支持接受任意数量的模板参数和非类型模板参数的模板)。不过,防止这种情况的一个简单方法是将概念定制为仅向量(例如
SpecializesVector
)。另一种方法是利用
std::vector
的所有模板参数都可以通过它的公共成员类型value_type
和allocator_type
来访问的这一事实。如果我们希望向量的
value_type
是算术的,我们可以这样写:While I also think that 康桓瑋's solution looks very neat and concise, using templated lambda's inside of a requires-clause actually makes potential error messages really unclear and hard to understand (which is supposed to be one the strong points of concepts). For example, when checking a type that has a member-function
vec()
which returns astd::array
instead of astd::vector
, the error messsage produced by Clang would be something like:相对于:
而且--在使用模板化lambda的概念时--当我们用
vec()
成员函数检查一个类型时,该成员函数返回一个没有算术value_type
的std::vector
,我们得到了与前面完全相同的错误消息:相对于:
ny6fqffe4#
只要
vec()
是公共类方法: