Подтвердить что ты не робот

Имеет ли оператор унарного + практическое применение?

Был ли унарный оператор + включен только для симметрии с унарным оператором - или он нашел практическое применение в коде С++?

Поиск здесь, я наткнулся на Какова цель унарного оператора "+" в C?, но единственные полезные сценарии там включают макросы препроцессора. Это хорошо знать, но они кажутся менее распространенными ситуациями и включают макросы. Существуют ли какие-либо варианты использования более распространенного кода на С++?

4b9b3361

Ответ 1

char ch = 'a';
std::cout << ch << '\n';
std::cout << +ch << '\n';

Первая вставка записывает символ a в cout. Вторая вставка записывает числовое значение ch в cout. Но это немного неясное; он полагается на компилятор, применяющий интегральные акции для оператора +.

Ответ 2

Симметрия с унарным - не совсем бесполезна; его можно использовать для акцента:

const int foo = -1;
const int bar = +1;

И перегруженный унарный + может использоваться для обозначения операции, которая дает то же логическое значение, что и его операнд, при выполнении некоторых нетривиальных вычислений. (Я видел, что это сделано для преобразований типов в Ada, что позволяет унарные +, но не преобразования) перегружаться.) У меня нет хорошего примера на С++, и можно утверждать, что он будет плохим стиль. (Опять же, я видел много заявлений о перегрузке <<.)

Что касается того, почему С++ имеет его, он, вероятно, в основном для согласованности с C, который добавил его в стандарт ANSI 1989 года. Обоснование C > просто говорит:

Унарный плюс был принят Комитетом C89 из нескольких реализаций, для симметрии с унарным минусом.

Ответ 3

Если вы явно избегаете семантики значений чисел для класса, любая перегрузка оператора ясна, чтобы не "делать так, как это делают int". В этом случае унарный плюс может иметь какое-либо значение, делая гораздо больше, чем просто возврат *this

Известный пример: Boost.Spirit унарный плюс для встроенного EBNF Kleene Plus создает правило парсера, которое позволяет его аргумент (правило парсера также) совпадать один или несколько раз.

Ответ 4

Унарный оператор + превращает значение l в значение r:

struct A {
  static const int value = 1;
};

// ...

int x = std::min(0, A::value);

Ой! Этот код не будет связываться, потому что кто-то забыл определить (а также объявить) A::value. std::min принимает свои аргументы по ссылке, поэтому A::value должен иметь адрес, с которым ссылка может привязываться к нему (технически одно правило определения говорит, что оно должно быть определено ровно один раз в программе.)

Nevermind, унарный плюс на помощь:

int x = std::min(0, +A::value);

Унарный плюс создает временное значение с тем же значением, а ссылка привязывается к временному, поэтому мы можем обойти отсутствующее определение.

Это не то, что вам нужно часто, но это практическое использование унарного оператора plus.

Ответ 5

Unary + применяет интегральные акции. Ответ @PeteBecker показывает один способ, который может быть полезен.

Для другого, обратите внимание, что тип нумерации с незаданной областью повышается до целочисленного типа, который может представлять все значения в enum. Поэтому в С++ 03, даже без С++ 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 );
}

Ответ 6

Немного поздно, но здесь очень искривленное использование, которое я наткнулся. По-видимому, оператор + может быть полезен (если не строго необходим) при разработке защитных мер вокруг возможности столкновения пустых токенов препроцессора. См. этот пост для более углубленного обсуждения.

Это практично, но отнюдь не приятно.