단항 더하기 연산자는 무엇을합니까?


87

단항 더하기 연산자는 무엇을합니까? 내가 찾은 몇 가지 정의가 있지만 ( 여기여기 ) 여전히 그것이 무엇을 위해 사용 될지 모릅니다. 아무 일도 안하는 것 같지만 이유가 있겠죠?


3
나는 생각 역사적 이유가 심각하게 과소 평가된다.
늑대

3
세 가지 다른 언어 태그가있는 질문은 매우 모호하거나 나쁩니다! 대답은 C # (오버로드 가능)과 C (오버로드 없음) 및 C ++ (오버로드 가능하지만 C에서 상속하므로 속성도 상 속됨)에 대해 매우 다릅니다.
legends2k

Eric Lippert의 C # 10 대 결함에 대한 링크를 추가하고 싶습니다. 단항 더하기 연산자는 다음과 같은 명예 멘션에서 찾을 수 있습니다. informit.com/articles/article.aspx?p=2425867 그는 기본적으로 제거하거나 추가하지 않아야한다고 말합니다.
Noel Widmer

답변:


57

필요하다고 느끼면 과부하가 걸릴 수 있습니다. 사전 정의 된 모든 유형의 경우 본질적으로 작동하지 않습니다.

no-op 단항 산술 연산자의 실제 사용은 매우 제한적이며 연산자 자체가 아닌 산술 표현식에서 값을 사용하는 결과와 관련되는 경향이 있습니다. 예를 들어, 더 작은 정수 유형에서로 확장을 강제 int하거나 표현식의 결과가 rvalue로 처리되어 비 const참조 매개 변수 와 호환되지 않는지 확인하는 데 사용할 수 있습니다 . 그러나 나는 이러한 사용이 가독성보다 골프 코딩에 더 적합하다고 제출합니다. :-)


7
아래의 여러 예에서 알 수 있듯이 이것은 실제로 사실이 아닙니다.
jkerian 2010 년

3
좋아요, 몇 가지 용도가 있음을 구매하겠습니다.하지만 아래에서 설명하는 대부분의 용도는 no-op 연산자를 사용하여 작성된 숫자 표현식이라는 사실과 관련이 있습니다. 예를 들어, intrvalue로 승격하여 결과는 표현식의 효과입니다. -ness는 + 연산자 자체가 아닙니다.
Jeffrey Hantin 2010 년

119

실제로 단항 더하기 C에서도 어떤 일을합니다. 피연산자에 대해 일반적인 산술 변환 을 수행하고 더 큰 너비의 정수가 될 수있는 새 값을 반환합니다. 원래 값이보다 작은 너비의 부호없는 정수 int이면 signed값으로도 변경됩니다 .

일반적으로 이것은 그다지 중요하지 않지만 효과가 있을 있으므로 정수가 양수임을 나타내는 일종의 "주석"으로 단항 더하기를 사용하는 것은 좋은 생각이 아닙니다 . 다음 C ++ 프로그램을 고려하십시오.

void foo(unsigned short x)
{
 std::cout << "x is an unsigned short" << std::endl;
}

void foo(int x)
{
 std::cout << "x is an int" << std::endl;
}

int main()
{
 unsigned short x = 5;
 foo(+x);
}

그러면 "x is an int"가 표시됩니다.

따라서이 예에서 단항 더하기는 다른 유형 부호를 가진 새 값을 생성했습니다 .


5
짧은 동등한 비교 int를 투여했을 때 결과를 주어진 생산하고 당신이있는 거 쓰는 코드는, 당신은 아마 다른 문제가있는 경우
거짓말 라이언

1
고마워요. (사이드 노트 : C에서는 foo 함수를 오버로드 할 수 없기 때문에 예제를 작동시킬 수 없었습니다.)
Binarian

무슨 뜻 an integer of greater width입니까?
yekanchi

이 컨텍스트에서 "너비"는 값과 관련된 스토리지의 바이트 수를 나타냅니다.
giles

41

K & R 두 번째 에디션에서 :

단항 +는 ANSI 표준의 새로운 기능입니다. 단항과의 대칭을 위해 추가되었습니다.-.


6
물론. * 이것이 역사적 이유입니다. C ++는이를 적용해야했기 때문에 오버로딩을 처리해야했습니다.
늑대

38

나는 음의 값과 구별되는 양의 값을 강조하기 위해 명확성을 위해 사용하는 것을 보았습니다.

shift(+1);
shift(-1);

그러나 그것은 매우 약한 사용입니다. 대답은 확실히 과부하입니다.


9
특히 같은 벡터를 다룰 vec3(+1,-1,-1)
때도이

28

내장 단항 +이 하는 한 가지는 lvalue를 rvalue로 바꾸는 것입니다. 예를 들어 다음과 같이 할 수 있습니다.

int x;
&x;

하지만 당신은 이것을 할 수 없습니다

&+x;

:)

PS "과부하"는 확실히 정답이 아닙니다. 단항 +은 C에서 상속되었으며 C에서 사용자 수준 연산자 오버로딩이 없습니다.


14

unary +가 수행하는 가장 중요한 것은 int보다 작은 데이터 유형에 대한 int로 유형 승격입니다. 이것은 std::cout숫자 데이터로 문자 데이터를 인쇄하려는 경우 매우 유용 할 수 있습니다 .

char x = 5;
std::cout << +x << "\n";

와 매우 다릅니다

char x=5;
std::cout << x << "\n";

과부하에도 사용할 수 있지만 실제로 과부하 거의 NOP 여야 합니다.


12

디버그 또는 어떤 이유로 든 원시 바이트의 숫자 값 (예 : char로 저장된 작은 숫자)을 인쇄해야하는 경우 unary +는 인쇄 코드를 단순화 할 수 있습니다. 중히 여기다

char c = 42;
cout << c << endl;           // prints "*\n", not what you want in this case
cout << (int)c << endl;      // prints "42\n", ok
cout << +c << endl;          // prints "42\n", much easier to type

이것은 간단한 예입니다. 단항 +가 텍스트 대신 숫자처럼 바이트를 처리하는 데 도움이 될 수있는 다른 경우가있을 것입니다.


4

역사적인 정보. C99 표준화위원회는 또한 언어의 또 다른 기능인 부동 소수점 상수 표현의 번역 시간 평가 금지라는 언어의 또 다른 기능을 달성하기 위해 재사용을 고려하고 있음을 입증했듯이, 기존의 단항 더하기 사용이 상당히 드물다고 생각했습니다. C 근거, 섹션 F.7.4에서 다음 인용문을 참조하십시오.

이 사양의 초기 버전에서는 변환 시간 상수 산술이 허용되었지만 피연산자에 적용될 때 단항 + 연산자가 상수 표현식의 변환 시간 평가를 금지 할 수있었습니다.

결국 대부분의 컨텍스트 (최소한 "as if"규칙까지)에서 실행 시간 평가가 시행되고 정적 초기화 프로그램을 사용하여 번역 시간 평가를 시행하는 기능을 사용하여 의미 체계가 반전되었습니다. 주요 차이점은 부동 소수점 예외 발생 및 기타 부동 소수점 반올림 또는 정밀도 설정 (있는 경우)에 있습니다.


3

별로. 의 오버로드를 허용하는 일반적인 주장은 오버로딩에 operator+()대한 실제 사용이 확실히 operator-()있다는 것입니다. 그리고 오버로딩을 허용 하지만 허용 하지 않는 경우 매우 이상하거나 비대칭 적일 것 입니다.operator-()operator+()

나는 처음에 Stroustrop에서이 주장을 읽었다 고 믿지만, 그것을 확인할 권리가 없습니다. 제가 틀렸을 수 있습니다.


3

Unary plus는 C에 있었는데, 아무것도하지 않았습니다 ( auto키워드 처럼 ). 그것을 가지지 않으려면 Stroustrup은 C와의 무상 비 호환성을 도입해야했을 것입니다.

일단 C ++에 있으면, 단항 마이너스처럼 오버로드 함수를 허용하는 것이 당연했고, Stroustrup이 이미 존재하지 않았다면 그 이유로 도입했을 수도 있습니다.

그래서 아무 의미가 없습니다. 예를 들어 +1.5를 -1.5와 반대로 사용하여 사물을 더 대칭 적으로 보이게하는 일종의 장식으로 사용할 수 있습니다. C ++에서는 오버로드 될 수 있지만 operator+()어떤 작업 을 수행하면 혼란 스러울 것입니다. 표준 규칙을 기억하십시오. 산술 연산자를 오버로드 할 때 ints 와 같은 작업을 수행하십시오.

그것이 존재하는 이유를 찾고 있다면 C의 초기 역사에 대해 뭔가를 찾으십시오. C가 실제로 설계되지 않았기 때문에 좋은 이유가 없다고 생각합니다. 쓸모없는 auto키워드 (아마도 static, 현재 C ++ 0x에서 재활용 됨)와 entry아무것도하지 않은 키워드 (나중에 C90에서 생략 됨)를 고려하십시오. Ritchie 또는 Kernighan이 운영자의 우선 순위에 문제가 있음을 깨달았을 때 이미 중단하고 싶지 않은 수천 줄의 코드가있는 세 개의 설치가 있었다고 말하는 유명한 이메일이 있습니다.


1
내가 본 유일한 비 산술 오버로드는 (+ term)이 하나 이상의 템을 의미하는 정규 표현식이나 문법에있었습니다. (이것은 상당히 표준적인 정규 표현식 구문입니다.)
Michael Anderson

정보 entry: ( stackoverflow.com/q/254395/153285 ). 요즘에는 여러 진입 점을 원한다면 테일 콜과 프로필 기반 최적화를 사용하십시오.
Potatoswatter 2010 년

나는 C99 에서조차도 extern volatile int foo;주어진 명령문 +foo;이 주어진 컴파일러 는 읽기가 일어 났는지 결정하기 위해 어떤 수단이 존재할 수있는 모든 플랫폼에서 표시된 주소의 읽기를 수행해야 한다고 믿습니다 . 비록 많은 컴파일러가 예의로서 그것을 할 것이지만, 그 진술이 단지 "foo"라면 이것이 요구 될 것인지 확신하지 못합니다.
supercat

2

이에 대한 출처를 인용 할 수는 없지만, 무손실 유형 변환을 의미하는 명시 적 유형 승격을위한 것임을 이해하게되었습니다. 그러면 전환 계층 구조의 맨 위에 배치됩니다.

  • 프로모션: new_type operator+(old_type)
  • 변환: new_type(old_type)
  • 캐스트: operator(new_type)(old_type)
  • 강제: new_type operator=(old_type)

물론, 그것은 제가 약 15 년 전에 읽은 마이크로 소프트 (정말 오래된) c / c ++ 매뉴얼 중 하나에있는 메모에 대한 저의 해석에서 나온 것입니다.


1
#include <stdio.h>
int main()
{
    unsigned short x = 5;
    printf ("%d\n",sizeof(+x)); 
    printf ("%d\n",sizeof(x)); 
    return 0;
}

위의 예에서 볼 수 있듯이, 단항 +는 실제로 유형, 크기 4 및 2를 각각 변경합니다. + x라는 표현이 실제로 sizeof로 계산된다는 게 이상하네요. 아마도 sizeof가 단항 +와 동일한 우선 순위를 가지고 있기 때문일 것입니다.


-1

나는 그것을 항상 양수로 만드는 데 사용할 수 있다고 생각합니다. 단항 + 연산자를 abs로 오버로드하십시오. 코드를 난독 화하고 싶지 않다면 동료 개발자를 혼동 할 가치가 없습니다. 그러면 잘 작동합니다.


그것은 모든 종류의 수학을
이상하게

어, 그래. 그래서하지 말라고 제안했습니다.
Patrick

1
@ Davy8 : 단항 플러스가 현재 단항 마이너스의 "반대" 라고 생각하는 이유는 무엇입니까 ? 비트 보수 연산자의 "반대"는 무엇입니까 ~? "반대"에 대한 정의가 무엇인지 잘 모르겠지만 현재 단항 더하기와 단항 빼기의 경험에 의해 편향된 것 같습니다.
ndkrempel

-1

내가 원래 대답에서 waaaayyy 떨어져 있었기 때문에 완전히 수정하십시오 .

이를 통해 유형의 명시 적 선언을 양수 값으로 처리 할 수 ​​있습니다 (대부분 수학적 작업이 아닌 것으로 생각합니다). 부정이 더 유용 할 것 같지만 여기에 차이를 만들 수있는 예가 있다고 생각합니다.

public struct Acceleration
{
    private readonly decimal rate;
    private readonly Vector vector;

    public Acceleration(decimal rate, Vector vector)
    {
        this.vector = vector;
        this.rate = rate;
    }

    public static Acceleration operator +(Acceleration other)
    {
        if (other.Vector.Z >= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public static Acceleration operator -(Acceleration other)
    {
        if (other.Vector.Z <= 0)
        {
            return other;
        }
        return new Acceleration(other.Rate, new Vector(other.vector.X, other.Vector.Y, -other.vector.Z));
    }

    public decimal Rate
    {
        get { return rate; }
    }

    public Vector Vector
    {
        get { return vector; }
    }
}

그것은 나에게 단항 연산처럼 보이지 않습니다. 2 개의 인수 (4 월과 5 월)가 필요하므로 이진이됩니다.
BlueMonkMN

그것은 바이너리 플러스입니다. 단항 더하기는 왼쪽 피연산자가없는 "+1"또는 일부입니다.
Jeffrey Hantin 2009

내 잘못이야. 내 CS101을 잊어 버렸습니다. 결정된.
Michael Meadows

3
프로덕션 코드에서 이러한 종류의 과부하를 발견하면 확실히 버그로 표시하고 가능한 한 빨리 수정합니다. 의 의미는 +값을 양수로 만드는 것이 아니라 기호를 변경하지 않은 상태로 두는 것입니다.
Arturo Torres Sánchez

-1

단순히 어떤 숫자가 양수인지 확인하는 데 사용됩니다.

예 :

int a=10;
System.out.println(+x);// prints 10(that means,that number 10 multiply by +1,{10*+1})

//if we use unary minus

int a=10;
System.out.println(-x);//prints -10(that means,that number 10 multiply by +1,{10*-1})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.