如何定义任意std::vector满足的概念?

我想要一个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>>;

有没有办法把它放在概念的名称中?

回答

我们首先编写一个变量模板来检查一个类型是否专用于一个模板:

template <typename T, template <typename...> class Z>
inline constexpr bool is_specialization_of = false;

template <template <typename...> class Z, class... Args>
inline constexpr bool is_specialization_of<Z<Args...>, Z> = true;

我们可以将其转化为一个概念:

template <typename T, template <typename...> class Z>
concept Specializes = is_specialization_of<T, Z>;

然后我们可以使用它来实现另一个概念:

template<typename T>
concept HasVector = requires (T t) {
    { t.vec() } -> Specializes<std::vector>;
};

如果你想再做进一步的检查,那只是增加了更多的要求。

template<typename T>
concept HasVector = requires (T t) {
    { t.vec() } -> Specializes<std::vector>;

    // or something along these lines
    requires Arithmetic<decay_t<decltype(t.vec()[0])>>;
    requires Arithmetic<range_value_t<decltype(t.vec())>>;
    // etc.
};


回答

#include <concepts>
#include <vector>

template<typename T>
concept Arithmetic = std::integral<T> || std::floating_point<T>;

template<typename T>
concept HasVector = requires (T t) {
  []<Arithmetic U, typename A>(std::vector<U,A> const&){}(t.vec());
};

演示。

  • @MarcGlisse。不,那是[不可能](https://godbolt.org/z/d3sKx1cY4)。
  • @Yakk-AdamNevraumont 已修复 🙂

以上是如何定义任意std::vector满足的概念?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>