在这个博客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}},表达式f
和Field
有道理。简而言之,我想要标量乘法和向量加法。尽管我可以在f * v1
中正确计算v1 + v2
,但是函数a3
告诉我main
的概念不满足。它正确地推导linear_comb
为VectorSpace<Field, Vector>
和Field
为float
。那么为什么上面没有将其视为有效的表达式?