Принципы разработки, лежащие в основе std :: ratio & lt; & gt;

Я смотрел на класс std::ratio<> из стандарта C ++ 11, что позволяет сделать рациональную арифметику во время компиляции.

Я обнаружил, что дизайн шаблона и операции, реализованные с классами, слишком сложны, и не нашел никаких причин, по которым они не могли бы просто использовать более простой и интуитивный подход, реализуя действительно простой рациональный класс и определяя constexpr функции для операторов. В результате класс стал бы проще в использовании, а преимущества времени компиляции остались бы.

Кто-нибудь имеет представление о преимуществах нынешнего std::ratio<> дизайн по сравнению с простой реализацией класса с использованием constexpr? На самом деле, я не могу найти преимущества для текущей реализации.

27

Решение

когда N2661 было предложено, ни один из авторов предложения не имел доступа к компилятору, который реализовал constexpr, И никто из нас не был готов предложить что-то, что мы не могли построить и протестировать. Так что, можно ли сделать лучший дизайн с constexpr не было даже частью рассмотрения для дизайна. Дизайн был основан только на тех инструментах, которые были доступны авторам в то время.

42

Другие решения

Решение constexpr решает совершенно другую проблему. std::ratio был создан для использования в качестве моста между переменными, которые используют разные единицы, а не в качестве математического инструмента. В этих обстоятельствах вы абсолютно обязательно хотите, чтобы отношение было частью типа. Решение constexpr не будет работать там. Например, не удастся реализовать std::duration без пространства времени выполнения и затрат времени выполнения, потому что каждый объект продолжительности должен был бы нести свою информацию о знаменателе / ​​знаменателе в пределах объекта.

14

std::ratio и окружающие его механизмы всегда будут работать во время компиляции благодаря метапрограммированию шаблонов и манипулированию типами. constexpr требуется только для запуска во время выполнения, когда константное выражение требуется средствами C ++ (такими как параметры шаблона или инициализация constexpr переменная).

Итак, что для вас важнее: выполнение во время компиляции или быть «более простым и интуитивно понятным»?

0

определение функций constexpr для оператора

Вы все еще можете сделать это поверх существующих std::ratio:

#include <ratio>

// Variable template so that we have a value
template<
std::intmax_t Num,
std::intmax_t Denom = 1
>
auto ratio_ = std::ratio<Num, Denom>{};

// Repeat for all the operators
template<
std::intmax_t A,
std::intmax_t B,
std::intmax_t C,
std::intmax_t D
>
constexpr typename std::ratio_add<std::ratio<A, B>, std::ratio<C, D>>::type
operator+(std::ratio<A, B>, std::ratio<C, D>) {}

// Printing operator
template<
std::intmax_t A,
std::intmax_t B
>
std::ostream &operator<<(std::ostream &os, std::ratio<A, B> r) {
return os << decltype(r)::num << "/" << decltype(r)::den;
}
#include <iostream>int main() {
std::cout << ratio_<1,2> + ratio_<1,3> << std::endl;
return 0;
}
5/6
0
По вопросам рекламы [email protected]