使用Ranges-v3库进行概念检查

时间:2019-03-19 04:46:25

标签: c++ c++-concepts

在这个博客post中,我看到了Eric Niebler解释了他对概念检查的看法。在我看来,这看起来像是在简单性和实用性之间取得了不错的平衡,所以我想尝试一下。

为了自己测试事物,我想出了向量空间的快速概念。这是代码:

#include <range/v3/utility/concepts.hpp>
#include <array>
#include <algorithm>
#include <string>

struct vector_space
{
    // Valid expressions
    template<typename Field, typename Vector>
    auto requires(Field &&f, Vector &&v1, Vector &&v2) -> decltype(
        ranges::concepts::valid_expr(
            f * v1,
            v1 + v2
        ));
};

template<typename Field, typename Vector>
constexpr bool VectorSpace()
{
    return ranges::concepts::models<vector_space, Field, Vector>();
}

template<typename Field, typename Vector,
         CONCEPT_REQUIRES_(VectorSpace<Field, Vector>())>
void linear_comb(Field f1, Vector v1, Field f2, Vector v2)
{
    return (f1 * v1) + (f2 * v2);
}

template <typename T, std::size_t dim>
std::array<T, dim> operator+(std::array<T, dim> const& a1,
                             std::array<T, dim> const& a2) {
    std::array<T, dim> res;
    std::transform(a1.begin(), a1.end(), a2.begin(),
                   res.begin(),
                   [](T const& e1, T const& e2) {
                       return e1 + e2;
                   });
    return res;
}

template <typename Field, typename T, std::size_t dim>
std::array<T, dim> operator*(std::array<T, dim> const& a,
                             Field f) {
    std::array<T, dim> res;
    std::transform(a.begin(), a.end(),
                   res.begin(),
                   [f](T const& e) {
                       return f * e;
                   });
    return res;
}

template <typename Field, typename T, std::size_t dim>
std::array<T, dim> operator*(Field f, std::array<T, dim> const& a) {
    return a * f;
}

int main() {
    std::string s1 = "hello";
    std::string s2 = "world";

    std::array<float, 4> a1{1.1f, 2.2f, 3.3f, 4.4f};
    std::array<float, 4> a2{4.4f, 3.3f, 2.2f, 1.1f};
    std::array<float, 4> a3 = (3.14f * a1) + (2.71f * a2);
    linear_comb(3.14f, a1, 2.71f, a2);
} 

如您所见,我想检查v1, v2的{​​{1}}和Vector的{​​{1}},表达式fField有道理。简而言之,我想要标量乘法和向量加法。尽管我可以在f * v1中正确计算v1 + v2,但是函数a3告诉我main的概念不满足。它正确地推导linear_combVectorSpace<Field, Vector>Fieldfloat。那么为什么上面没有将其视为有效的表达式?

0 个答案:

没有答案