해결책
필요하다고 느끼면 과부하가 걸리야합니다. 사전 정의 된 모든 유형의 경우 본질적으로 No-OP입니다.
NO-OP 단독 산술 연산자의 실제 용도는 상당히 제한적이며 연산자 자체가 아닌 산술 표현식에서 값을 사용한 결과와 관련이있는 경향이 있습니다. 예를 들어, 더 작은 적분 유형에서 int
, 또는 표현식의 결과가 rvalue로 취급되므로 비가 아닌 것과 호환되지 않도록하십시오.const
참조 매개 변수. 그러나 이러한 용도는 가독성보다 코드 골프에 더 적합하다고 제출합니다. :-)
다른 팁
사실, unary plus 하다 C.조차도 무언가를 수행합니다 일반적인 산술 변환 피연산자에서 새로운 값을 반환하며,이 값은 더 큰 폭의 정수가 될 수 있습니다. 원래 값이 서명되지 않은 너비의 정수 인 경우 int
, 그것은 a로 변경됩니다 signed
가치도 있습니다.
일반적으로 이것은 그렇게 중요하지는 않지만 그것은 중요합니다 ~할 수 있다 효과가 있습니다 ~ 아니다 정수가 긍정적이라는 것을 나타내는 일종의 "의견"으로 unery plus를 사용하는 것이 좋습니다. 다음 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는 int"가 표시됩니다.
이 예에서는 Unary Plus가 다른 유형의 새로운 값을 만들었습니다. 그리고 서명.
K & R Second Edition에서 :
unery +는 ANSI 표준으로 새롭습니다. 단시와 대칭으로 추가되었습니다.
나는 긍정적 값을 음수 값과 구별하는 것으로 강조하기 위해 명확성에 사용되는 것을 보았습니다.
shift(+1);
shift(-1);
그러나 그것은 꽤 약한 용도입니다. 대답은 분명히 과부하입니다.
내장 된 단지 한 가지 +
LAS는 lValue를 rvalue로 바꾸고 있습니다. 예를 들어, 당신은 이것을 할 수 있습니다
int x;
&x;
그러나 당신은 이것을 할 수 없습니다
&+x;
:)
추신 "과부하"는 확실히 정답이 아닙니다. 단금 +
C에서 상속되었고 C에는 사용자 수준 운영자 과부하가 없습니다.
Unary +가 달성하는 가장 중요한 것은 Int 데이터 유형보다 작은 INT에 대한 유형 프로모션입니다. 이것은 숯 데이터를 사용하여 인쇄하려는 경우 매우 유용 할 수 있습니다. std::cout
숫자 데이터로.
char x = 5;
std::cout << +x << "\n";
매우 다릅니다
char x=5;
std::cout << x << "\n";
과부하에도 사용할 수 있지만 실제로는 과부하가 발생합니다. ~해야 한다 거의 NOP가 되십시오.
디버그 또는 다른 이유에 대해 원시 바이트 (예 : 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
이것은 단지 빠른 예입니다. unery +가 텍스트가 아닌 숫자처럼 숫자를 더 많이 취급 할 수있는 다른 시간이 있다고 확신합니다.
역사적인 멍청한. C99 표준화위원회는 또한 언어의 다른 기능을 달성하기 위해 재사용 한 것으로 간주되는 바와 같이, Unary Plus의 기존 사용이 상당히 드물다고 생각했다. C Rationale 섹션 F.7.4의 다음 인용문을 참조하십시오.
이 사양의 초기 버전은 번역 시간 상수 산술을 허용했지만, 피연산자에 적용될 때는 일정한 표현식의 번역 시간 평가를 억제하기 위해 Unary + 연산자에게 권한을 부여했습니다.
결국, 시맨틱은 대부분의 상황에서 런타임 평가가 시행되면서 (적어도 "eve"규칙까지) 정적 초기화기를 사용하여 번역 시간 평가를 시행 할 수있는 능력으로 반전되었습니다. 주요 차이점은 부동 소수점 예외의 발생 및 존재하는 다른 부동 소수점 반올림 또는 정밀 설정에 있습니다.
별로. 과부하를 허용하는 일반적인 주장 operator+()
과부하를위한 실제 세계 용도가 확실히 있다는 것입니다. operator-()
, 그리고 그럴 것입니다 매우 과부하를 허용한다면 이상한 (또는 비대칭 적) operator-()
하지만 operator+()
.
나는 Stroustrop 에서이 주장을 처음 읽은 것이라고 생각하지만, 그것을 확인할 권리가있는 책이 없습니다. 제가 틀렸을 수 있습니다.
Unary Plus는 C에 존재했으며 절대 아무것도하지 않았습니다 ( auto
예어). 그것을 갖지 않기 위해, Stroustrup은 C와의 무능력을 도입해야했을 것입니다.
일단 C ++에 있으면 Unory 마이너스와 마찬가지로 과부하 기능을 허용하는 것이 당연했으며 Stroustrup은 아직 존재하지 않았다면 그런 이유로 도입했을 수 있습니다.
따라서 아무 의미가 없습니다. 예를 들어 +1.5를 -1.5와 반대로 사용하여 물건을 대칭으로 보이게하기 위해 일종의 장식으로 사용할 수 있습니다. C ++에서는 과부하 할 수 있지만 혼란 스러울 것입니다. operator+()
무엇이든합니다. 표준 규칙을 기억하십시오 : 산술 연산자를 과부하 할 때 int
s do.
그 이유가있는 이유를 찾고 있다면 C의 초기 역사에 대해 무언가를 찾으십시오. C가 실제로 설계되지 않았기 때문에 좋은 이유가 없다고 생각합니다. 쓸모없는 것을 고려하십시오 auto
키워드 (아마도 아마도 static
, 이제 C ++ 0x로 재활용되고 있습니다. entry
아무것도하지 않은 키워드 (그리고 나중에 C90에서 생략). Ritchie 또는 Kernighan은 운영자 우선 순위에 문제가 있다는 것을 깨달았을 때 이미 수천 개의 코드 라인이있는 세 개의 설치가 이미 3 번의 설치가 있었다고 말하는 유명한 이메일이 있습니다.
나는 이것에 대한 어떤 출처도 인용 할 수 없지만 명백한 유형 홍보를위한 것임을 이해하게되었습니다. 이는 무손실 유형 변환을 의미합니다. 그것은 변환 계층의 맨 위에 놓고,
- 홍보:
new_type operator+(old_type)
- 변환:
new_type(old_type)
- 깁스:
operator(new_type)(old_type)
- 강제:
new_type operator=(old_type)
물론, 그것은 약 15 년 전에 읽은 Microsoft (정말 오래된) C/C ++ 매뉴얼 중 하나의 메모 해석에서 비롯된 것입니다.
#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가 unery +와 동일한 우선 순위가 있다는 사실 때문일 것입니다.
나는 당신이 그것을 사용할 수 있다고 항상 숫자를 긍정적으로 만들 수 있다고 생각합니다. unary + 연산자에게 ABS가되도록 과부하하십시오. 실제로 코드를 난독 화하고 싶지 않다면 동료 개발자를 혼란스럽게 할 가치가 없습니다. 그런 다음 잘 작동했습니다.
편집 완전히 다시 작성했었기 때문에,나는 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; }
}
}