我是C++20概念的新手,我正在努力定义一个浮点连续范围的概念。我设法写了一个概念,或多或少地工作,但我不能用它来强制一个特定的浮点类型,如float
或double
。
下面是我的第一次尝试:
#include <concepts>
#include <iostream>
#include <ranges>
#include <vector>
template<class R>
concept FloatingPointRange =
std::ranges::contiguous_range<R> &&
std::floating_point<std::ranges::range_value_t<R>>;
template<std::floating_point F>
class C {
public:
explicit C(F x) : x_{x} {}
void add(FloatingPointRange auto const& r) {
for (auto const& v : r) {
x_ += v;
}
}
F get() {
return x_;
}
private:
F x_;
};
void print(FloatingPointRange auto const& r) {
for (const auto& v: r) {
std::cout << v << " ";
}
std::cout << "\n";
}
int main() {
std::vector<float> v = {100, 100};
C<float> c{10};
std::cout << c.get() << "\n"; // This line prints "10".
c.add(v);
std::cout << c.get() << "\n"; // This line prints "210".
print(v); // This line prints "100 100".
return 0;
}
但是,当将double
值的vector
传递给C
类的add
函数时,此概念也起作用,而不会导致编译错误,如下所示。
std::vector<double> w = {1000, 1000, 1000, 1000};
c.add(w); // This works but I would like to get a compilation error because F = float here.
所以在第二次尝试中,我尝试使用参数化概念,如果浮点类型不匹配,这确实会导致C
类的add
函数出现编译错误,但是它会破坏print
函数。
#include <concepts>
#include <iostream>
#include <ranges>
#include <vector>
template<class R, class F>
concept FloatingPointRange =
std::ranges::contiguous_range<R> &&
std::floating_point<F> &&
std::same_as<std::ranges::range_value_t<R>, F>;
template<std::floating_point F>
class C {
public:
explicit C(F x) : x_{x} {}
void add(FloatingPointRange<F> auto const& r) {
for (auto const& v : r) {
x_ += v;
}
}
F get() {
return x_;
}
private:
F x_;
};
template<std::floating_point F>
void print(FloatingPointRange<F> auto const& r) {
for (auto const& v: r) {
std::cout << v << " ";
}
std::cout << "\n";
}
int main() {
std::vector<float> v = {100, 100};
std::vector<double> w = {1000, 1000, 1000, 1000};
C<float> c{10};
std::cout << c.get() << "\n"; // This line prints "10"
c.add(v);
std::cout << c.get() << "\n"; // This line prints "210"
c.add(w); // This line causes a compilation error as expected.
print(v); // This line causes a compilation error.
print(w); // Same error as the previous line.
return 0;
}
使用这种方法,当我按预期调用c.add(w)
时,我得到了一个编译错误。但是,我也得到了print(v)
和print(w)
的编译错误(模板参数推导/替换失败)。
您可以在此处找到这两种尝试:https://godbolt.org/z/b8f4PvE3G(您可以在开头注解#define GENERIC
行,以便在我的两次尝试之间切换)。
总而言之,我在定义一个连续的浮点值范围的过程中遇到了麻烦,这个范围既可以拒绝对带有错误浮点类型的C::add
的调用,又可以接受对所有浮点类型的print
的调用,所以如果有人能帮助我解决这个问题,我将不胜感激。
1条答案
按热度按时间b4lqfgs41#
可以为
FloatingPointRange
概念定义缺省模板参数并且make
print
仅将参数约束为FloatingPointRange
,F
未显式提供,它可以接受任何范围的浮点类型:Demo