英文:
Concept for floating-point contiguous range in C++20
问题
I'll provide translations of the code you provided, excluding the code itself. Here's the translated content:
I'm new to C++20 concepts and I'm struggling to define a concept for a floating-point contiguous range. I managed to write a concept that works more or less but I cannot use it to enforce a specific floating-point type such as `float` or `double`.
Here is my first attempt:
However, this concept also works when passing a `vector` of `double` values to the `add` function of the `C` class instead of causing a compilation error as shown below.
So in a second attempt I tried to use a parametrized concept instead. This indeed causes a compilation error for the `add` function of the `C` class if the floating-point type does not match. However, it breaks the `print` function.
With this approach, I get a compilation error when calling `c.add(w)` as expected. However, I also get a compilation error for `print(v)` and `print(w)` (template argument deduction/substitution failed).
You can find these two attempts here: .
To summarize, I'm stuck on the way to define a contiguous range of floating-point values that would both reject calls to `C::add` with the wrong floating-point type and accept calls to `print` for all floating-point types. So I would be grateful if anyone could help me to solve my issue.
If you have any specific questions or need further assistance, please feel free to ask.
英文:
I'm new to C++20 concepts and I'm struggling to define a concept for a floating-point contiguous range. I managed to write a concept that works more or less but I cannot use it to enforce a specific floating-point type such as float
or double
.
Here is my first attempt:
#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;
}
However, this concept also works when passing a vector
of double
values to the add
function of the C
class instead of causing a compilation error as shown below.
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.
So in a second attempt I tried to use a parametrized concept instead. This indeed causes a compilation error for the add
function of the C
class if the floating-point type does not match. However, it breaks the print
function.
#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;
}
With this approach I get a compilation error when calling c.add(w)
as expected. However, I also get a compilation error for print(v)
and print(w)
(template argument deduction/substitution failed).
You can find these two attempts here: https://godbolt.org/z/b8f4PvE3G (you can comment the #define GENERIC
line at the beginning to switch between my two attempts).
To summarize, I'm stuck on the way to define a contiguous range of floating-point values that would both reject calls to C::add
with the wrong floating-point type and accept calls to print
for all floating-point types. So I would be grateful if anyone could help me to solve my issue.
答案1
得分: 1
你可以为 FloatingPointRange
概念定义一个默认的模板参数:
template<class R, class F = std::ranges::range_value_t<R>>
concept FloatingPointRange =
std::ranges::contiguous_range<R> &&
std::floating_point<F> &&
std::same_as<std::ranges::range_value_t<R>, F>;
并且可以使 print
仅对没有显式提供 F
参数的 FloatingPointRange
进行约束,这可以接受任何浮点数类型的范围:
void print(FloatingPointRange auto const& r) {
for (auto const& v: r) {
std::cout << v << " ";
}
std::cout << "\n";
}
英文:
You can define a default template parameter for the FloatingPointRange
concept
template<class R, class F = std::ranges::range_value_t<R>>
concept FloatingPointRange =
std::ranges::contiguous_range<R> &&
std::floating_point<F> &&
std::same_as<std::ranges::range_value_t<R>, F>;
and make print
only constrain the argument to be a FloatingPointRange
for which F
is not explicitly provided, which can accept any range of floating-point types:
void print(FloatingPointRange auto const& r) {
for (auto const& v: r) {
std::cout << v << " ";
}
std::cout << "\n";
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论