Имеет ли оператор unary + практическое применение?
был унарный +
оператора включен только для симметрии с унарным -
оператор, или он находит практическое применение в коде C++?
поиск здесь, я наткнулся на какова цель унарного оператора ' + ' в C?, но единственные полезные сценарии там включают макросы препроцессора. Это хорошо известно, но они кажутся менее распространенными ситуациями и включают макросы. Существуют ли какие-либо варианты использования с более распространенным кодом C++?
6 ответов
char ch = 'a';
std::cout << ch << '\n';
std::cout << +ch << '\n';
первая вставка записывает символ a
to cout
. Вторая вставка записывает числовое значение ch
to cout
. Но это немного неясно; он полагается на компилятор, применяющий интегральные рекламные акции для +
оператора.
симметрии с унарным -
не совсем бесполезно; его можно использовать для акцента:
const int foo = -1;
const int bar = +1;
и перегружен унарный +
может использоваться для обозначения операции, которая дает то же самое логическое значение как его операнд при выполнении некоторых нетривиальных вычислений. (Я видел, как это делается для преобразования типов в Ada, что позволяет unary +
, но не преобразования, которые будут перегружены.) У меня нет хорошего примера C++, и можно поспорить что это будет некрасиво. (Опять же, я видел много разглагольствований о перегрузке <<
.)
по состоянию на почему C++ имеет его, вероятно, в основном для согласованности с C, который добавил его со стандартом ANSI 1989 года. The C Обоснование просто говорит:
унарный плюс был принят Комитетом C89 из нескольких реализации, для симметрии с унарным минусом.
Если вы явно остаетесь в стороне от любой семантики числового значения для класса,любой перегрузка оператора понятна, чтобы не "делать так, как делают ints". В этом случае унарный плюс может получить любой смысл, делая гораздо больше, чем просто возвращение *this
яркий пример: импульс.Дух унарный плюс для встроенного EBNF в Kleene Plus генерирует правило парсера, которое позволяет его аргументу (правило парсера также) совпадать один или несколько раз.
унарный +
оператор превращает значение lvalue в значение rvalue:
struct A {
static const int value = 1;
};
// ...
int x = std::min(0, A::value);
Ах нет! Этот код не будет связан, потому что кто-то забыл определить (а также объявить) A::value
. std::min
принимает свои аргументы по ссылке so A::value
должен иметь адрес, чтобы ссылка могла привязываться к нему (технически, правило одного определения говорит, что оно должно быть определено точно один раз в программе.)
неважно, унарный плюс на помощь:
int x = std::min(0, +A::value);
унарный плюс создает временное с тем же значением, и ссылка привязывается к временному, поэтому мы можем работать вокруг отсутствующего определения.
это не то, что вам нужно часто, но это практическое использование унарного оператора plus.
Unary + применяет интегральные акции. Ответ @PeteBecker показывает один из способов, который может быть полезен.
для другого обратите внимание, что тип перечисления без области повышается до целочисленного типа, который может представлять все значения в enum
. Так что в C++03, даже без c++11 std::underlying_type<T>
, вы могли бы сделать:
enum MyBitMask {
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4,
Flag4 = 0x8000000
};
inline MyBitMask operator&(MyBitMask x, MyBitMask y) {
return static_cast<MyBitMask>( +x & +y );
}
inline MyBitMask operator|(MyBitMask x, MyBitMask y) {
return static_cast<MyBitMask>( +x | +y );
}
немного поздно, но вот очень закрученный, я наткнулся на. Видимо +
оператор может быть полезен (если, возможно, не строго необходим) при разработке гарантий вокруг возможности столкнуться с пустыми токенами препроцессора. См.этот пост для более углубленного обсуждения.
это практично, но отнюдь не приятное.