Я наткнулся на это Пример ржавчины в Википедии и мне интересно, если это возможно, чтобы преобразовать его в семантически эквивалентный код C ++?
Программа определяет рекурсивную структуру данных и реализует методы на ней. Для рекурсивных структур данных требуется слой косвенности, который обеспечивается уникальным указателем, построенным через box
оператор. (Они аналогичны типу библиотеки C ++ std::unique_ptr
Правда, с большей статической гарантией безопасности.)
fn main() {
let list = box Node(1, box Node(2, box Node(3, box Empty)));
println!("Sum of all values in the list: {:i}.", list.multiply_by(2).sum());
}
// `enum` defines a tagged union that may be one of several different kinds
// of values at runtime. The type here will either contain no value, or a
// value and a pointer to another `IntList`.
enum IntList {
Node(int, Box<IntList>),
Empty
}
// An `impl` block allows methods to be defined on a type.
impl IntList {
fn sum(self) -> int {
match self {
Node(value, next) => value + next.sum(),
Empty => 0
}
}
fn multiply_by(self, n: int) -> Box<IntList> {
match self {
Node(value, next) => box Node(value * n, next.multiply_by(n)),
Empty => box Empty
}
}
}
Видимо в версии C ++ Rusts enum
следует заменить на union
Ржавчина Box
следует заменить на std::unique_ptr
и ржавеет Узел кортежа должно быть std::tuple
типа, но я просто не могу понять, как написать эквивалентную реализацию на C ++.
Я знаю, что это, вероятно, не практично (и определенно не является правильным способом сделать что-то в C ++), но я просто хотел посмотреть, как эти языки сравниваются (функции C ++ 11 достаточно гибкие для такого рода действий?). Я также хотел бы сравнить сгенерированную компилятором сборку для семантически эквивалентных реализаций (если это возможно).
отказЯ не эксперт C ++ 11. Потребляйте с необходимой дозой соли.
Как прокомментировали другие, есть несколько способов интерпретации вашего вопроса. Я собираюсь пойти с чрезмерно агрессивной интерпретацией, так как она единственная интересная:
нет, это не можно перевести этот код Rust в эквивалентный код C ++. Можете ли вы перевести его в программу, которая обеспечивает тот же результат? Они оба завершены, поэтому, конечно, вы можете. Можете ли вы перевести это так, чтобы все семантика в оригинале сохранилась? Нет.
Большинство из этого Можно быть переведены так, чтобы сохранить реальное поведение. Rust-стиль enum
s можно заменить на struct
с полем тега и union
наряду с написанием соответствующих перегрузок операторов, чтобы обеспечить правильное уничтожение членов только вариант, который на самом деле хранится. Вы можете (предположительно) использовать unique_ptr
таким образом, что память выделяется первый а затем новое значение записывается непосредственно в распределение, поэтому нет копии. Я верю, что вы можете переписать fn sum(self)
так что он использует rvalue this
(хотя я никогда не делал этого, поэтому я мог легко ошибаться).
Но одна вещь, которую вы не могу do в C ++, насколько мне известно, является копией линейных типов. Нет никакого способа статически принудить, что перемещенное значение не может быть использовано снова. Лучшее, что вы можете сделать, — это проверки во время выполнения, которые обязательно должны включать дополнительные издержки. Это также играет на то, почему вы не можете иметь необнуляемый unique_ptr
: вы никогда не сможете переместить его, так как вы должны оставить перемещенную переменную в годный к употреблению государство.
Теперь, что было сказано, я должен отказаться от предыдущего заявления, отметив, что В настоящее время, компилятор Rust испускает некоторые проверки во время выполнения для отброшенного (то есть перемещены) значения, в виде флажков сброса. Последний план, который я проверял, заключался в том, чтобы убрать эти проверки во время выполнения в пользу чисто статического разрушения, возможно до версии 1.0.