Сообщение Re[3]: Тема constexpr в классах от 05.04.2026 10:31
Изменено 05.04.2026 10:51 rg45
Re[3]: Тема constexpr в классах
Здравствуйте, LaptevVV, Вы писали:
LVV>Спасибо.
R>>Или я не уловил суть вопроса.
LVV>Я не совсем четко сформулировал.
LVV>Попробую снова.
LVV>Мне для студентов максимально просто надо.
LVV>Вот написал я класс для работы с обыкновенными рациональными дробями (числитель/знаменатель).
LVV>Например:
LVV>
LVV>А как его в constexpr превратить ?
LVV>Возможно ли ?
LVV>Без шаблонов и прочих сложностей.
Просто добавляешь constexpr к кострукторам и НЕКОТОРЫМ функциям-членам (собственно подход тот же самый, который используют std::string и многие другие классы стандартной библиотеки):
https://gcc.godbolt.org/z/Y11b8z3hG
Таким образом, лёгким движением руки объекты Fraction становятся доступны для использования в компайл-тайм:
LVV>Спасибо.
R>>Или я не уловил суть вопроса.
LVV>Я не совсем четко сформулировал.
LVV>Попробую снова.
LVV>Мне для студентов максимально просто надо.
LVV>Вот написал я класс для работы с обыкновенными рациональными дробями (числитель/знаменатель).
LVV>Например:
LVV>
LVV>class Fraction // класс «рациональная дробь»
LVV>{ int num {0}, denum{1}; // поля закрыты
LVV> void reduce() // закрытый метод
LVV> { int t = std::gcd(num, denum); // НОД
LVV> num /= t; denum /= t; // сокращение
LVV> }
LVV> public:
LVV> Fraction(int num, int denum = 1){
this->>num = num; this->denum = denum;
LVV> reduce();
LVV> }
LVV> Fraction() = default; // синтезировать
LVV> void print(char last = '\n'){
LVV> std::cout <<"<"<< num <<"/"<< denum <<">"<< last;
LVV> }
LVV>};
LVV>LVV>А как его в constexpr превратить ?
LVV>Возможно ли ?
LVV>Без шаблонов и прочих сложностей.
Просто добавляешь constexpr к кострукторам и НЕКОТОРЫМ функциям-членам (собственно подход тот же самый, который используют std::string и многие другие классы стандартной библиотеки):
https://gcc.godbolt.org/z/Y11b8z3hG
class Fraction // класс «рациональная дробь»
{
int num{ 0 }, denum{ 1 }; // поля закрыты
constexpr void reduce() { // закрытый метод
assert(denum != 0);
int t = std::gcd(num, denum); // НОД
num /= t; denum /= t; // сокращение
}
public:
constexpr Fraction(int num, int denum = 1)
: num(num), denum(denum)
{
assert(denum != 0);
reduce();
}
constexpr Fraction() = default; // синтезировать
constexpr double make_double() const {
assert(denum != 0);
return double(num) / denum;
}
constexpr explicit operator double() const { return make_double(); }
void print(char last = '\n') {
std::cout << "<" << num << "/" << denum << ">" << last;
}
};Таким образом, лёгким движением руки объекты Fraction становятся доступны для использования в компайл-тайм:
static_assert(Fraction(3,2).make_double() == 1.5);Re[3]: Тема constexpr в классах
Здравствуйте, LaptevVV, Вы писали:
LVV>Спасибо.
R>>Или я не уловил суть вопроса.
LVV>Я не совсем четко сформулировал.
LVV>Попробую снова.
LVV>Мне для студентов максимально просто надо.
LVV>Вот написал я класс для работы с обыкновенными рациональными дробями (числитель/знаменатель).
LVV>Например:
LVV>
LVV>А как его в constexpr превратить ?
LVV>Возможно ли ?
LVV>Без шаблонов и прочих сложностей.
Просто добавляешь constexpr к кострукторам и НЕКОТОРЫМ функциям-членам (собственно подход тот же самый, который используют std::string и многие другие классы стандартной библиотеки):
https://gcc.godbolt.org/z/Y11b8z3hG
Таким образом, лёгким движением руки объекты Fraction становятся доступны для использования в компайл-тайм:
LVV>Спасибо.
R>>Или я не уловил суть вопроса.
LVV>Я не совсем четко сформулировал.
LVV>Попробую снова.
LVV>Мне для студентов максимально просто надо.
LVV>Вот написал я класс для работы с обыкновенными рациональными дробями (числитель/знаменатель).
LVV>Например:
LVV>
LVV>class Fraction // класс «рациональная дробь»
LVV>{ int num {0}, denum{1}; // поля закрыты
LVV> void reduce() // закрытый метод
LVV> { int t = std::gcd(num, denum); // НОД
LVV> num /= t; denum /= t; // сокращение
LVV> }
LVV> public:
LVV> Fraction(int num, int denum = 1){
this->>num = num; this->denum = denum;
LVV> reduce();
LVV> }
LVV> Fraction() = default; // синтезировать
LVV> void print(char last = '\n'){
LVV> std::cout <<"<"<< num <<"/"<< denum <<">"<< last;
LVV> }
LVV>};
LVV>LVV>А как его в constexpr превратить ?
LVV>Возможно ли ?
LVV>Без шаблонов и прочих сложностей.
Просто добавляешь constexpr к кострукторам и НЕКОТОРЫМ функциям-членам (собственно подход тот же самый, который используют std::string и многие другие классы стандартной библиотеки):
https://gcc.godbolt.org/z/Y11b8z3hG
class Fraction // класс «рациональная дробь»
{
int num{ 0 }, denum{ 1 }; // поля закрыты
constexpr void reduce() { // закрытый метод
assert(denum != 0);
int t = std::gcd(num, denum); // НОД
num /= t; denum /= t; // сокращение
}
public:
constexpr Fraction(int num, int denum = 1)
: num(num), denum(denum)
{
assert(denum != 0);
reduce();
}
constexpr Fraction() = default; // синтезировать
constexpr double make_double() const {
assert(denum != 0);
return double(num) / denum;
}
constexpr explicit operator double() const { return make_double(); }
void print(char last = '\n') {
std::cout << "<" << num << "/" << denum << ">" << last;
}
};Таким образом, лёгким движением руки объекты Fraction становятся доступны для использования в компайл-тайм:
static_assert(Fraction(3,2).make_double() == 1.5);
static_assert(double(Fraction(3,2)) == 1.5);