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