C ++ 11 — Возможно ли написать этот код Rust в семантически эквивалентный код C ++?

Я наткнулся на это Пример ржавчины в Википедии и мне интересно, если это возможно, чтобы преобразовать его в семантически эквивалентный код 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 достаточно гибкие для такого рода действий?). Я также хотел бы сравнить сгенерированную компилятором сборку для семантически эквивалентных реализаций (если это возможно).

1

Решение

отказЯ не эксперт C ++ 11. Потребляйте с необходимой дозой соли.

Как прокомментировали другие, есть несколько способов интерпретации вашего вопроса. Я собираюсь пойти с чрезмерно агрессивной интерпретацией, так как она единственная интересная:

нет, это не можно перевести этот код Rust в эквивалентный код C ++. Можете ли вы перевести его в программу, которая обеспечивает тот же результат? Они оба завершены, поэтому, конечно, вы можете. Можете ли вы перевести это так, чтобы все семантика в оригинале сохранилась? Нет.

Большинство из этого Можно быть переведены так, чтобы сохранить реальное поведение. Rust-стиль enums можно заменить на structс полем тега и unionнаряду с написанием соответствующих перегрузок операторов, чтобы обеспечить правильное уничтожение членов только вариант, который на самом деле хранится. Вы можете (предположительно) использовать unique_ptr таким образом, что память выделяется первый а затем новое значение записывается непосредственно в распределение, поэтому нет копии. Я верю, что вы можете переписать fn sum(self) так что он использует rvalue this (хотя я никогда не делал этого, поэтому я мог легко ошибаться).

Но одна вещь, которую вы не могу do в C ++, насколько мне известно, является копией линейных типов. Нет никакого способа статически принудить, что перемещенное значение не может быть использовано снова. Лучшее, что вы можете сделать, — это проверки во время выполнения, которые обязательно должны включать дополнительные издержки. Это также играет на то, почему вы не можете иметь необнуляемый unique_ptr: вы никогда не сможете переместить его, так как вы должны оставить перемещенную переменную в годный к употреблению государство.

Теперь, что было сказано, я должен отказаться от предыдущего заявления, отметив, что В настоящее время, компилятор Rust испускает некоторые проверки во время выполнения для отброшенного (то есть перемещены) значения, в виде флажков сброса. Последний план, который я проверял, заключался в том, чтобы убрать эти проверки во время выполнения в пользу чисто статического разрушения, возможно до версии 1.0.

3

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


По вопросам рекламы [email protected]