2012-10-26 4 views
16

요약 : 은 bool으로 변환되고 boolint으로 변환되므로 왜 nullptrint으로 변환되지 않습니까?nullptr을 int로 변환 할 수없는 이유는 무엇입니까?

void f(bool); 
f(nullptr);  // fine, nullptr converts to bool 

그리고이 괜찮 :

이 코드는 괜찮

bool b; 
int i(b);  // fine, bool converts to int 

왜이 괜찮 아닌가요?

void f(int); 
f(nullptr);  // why not convert nullptr to bool, then bool to int? 
+2

변환이 어떻게 되겠습니까? –

+3

컴파일러는 전달한 것을 함수가 받아들이는 것에서 만 * 암시 적으로 변환합니다. 이것은 nullptr뿐만 아니라 본질적으로 모든 유형에 적용됩니다. 예를 들어,'char' 로의 변환을 가진 타입을 정의하고'int'를 취하는 함수에 그것을 전달하려고하면'char'으로 암시 적 변환을 지원하더라도 실패 할 것입니다. 'char'에서'int'로 암시 적으로 변환합니다. –

+1

@JerryCoffin 컴파일러는 암시 적 변환을 두 번 이상 수행합니다. 사용자 정의 변환은 하나만 수행되지만 규칙에 따라 여러 번 다른 전환을 집계 할 수 있습니다. 최대 하나의 변환이 주어진 카테고리에 적용될 수있는 규칙이 있으며, 다양한 정수형에 대한'nullptr_t'와'bool'과'bool'은 모두 "Conversion"범주에 있습니다 (13.2.2.1.1 참조). –

답변

28

정확히 nullptr의 주요 아이디어이기 때문에.

nullptr는이 문제를 방지하기 위해 의미되었다 : int로 전환했다

struct myclass {}; 

void f(myclass* a) { std::cout << "myclass\n"; } 
void f(int a) { std::cout << "int\n"; } 

// ... 

f(NULL); // calls void f(int) 

nullptr 경우이 문제가 발생합니다.

그래서 "bool으로 변환 될 수 있습니까?"

Syntax- "suggarness"

int* a = nullptr; 
if (a) { 
} 

보다 훨씬 좋아 보이는 : 표준의 §4.1에서

if (a == nullptr) { 
} 
+4

그건 답이 아닙니다! –

+9

@ David : 아니야. 'nullptr'의 이유는 포인터 타입이 아닌 다른 것으로 변환되지 않기 때문입니다. – Xeo

+2

@David : 무엇입니까? – RiaD

18

, 그것은 변환을 수행하는 방법을 말한다

표준 변환은 내장 된 의미를 가진 암시 적 변환입니다. 4 절은 이러한 변환의 전체 집합을 나열합니다. 표준 변환 시퀀스는 다음 순서로 표준 변환 시퀀스입니다.

- 0 또는 다음 세트에서 하나의 변환 : 왼쪽에서 오른쪽으로의 변환, 배열에서 포인터로의 변환 및 함수에서 포인터로의 변환 .

- 통합 프로모션, 부동 소수점 프로모션, 정수 변환, 부동 소수점 변환, 부동 소수점 변환, 포인터 변환, 멤버 변환 포인터 및 부울 변환 중에서 0 또는 1 변환

- 0 또는 하나의 자릿수 변환.

그래서 컴파일러는 위의 변환 유형 중 일부 또는 모두를 임의로 또는 전부를 "0 또는 1 변환"합니다. 그리고 그것은 입니다. 정말 좋은 것입니다..

+0

+1 : tite 대답, Seth.나에게 말하기는 어렵지만 여기에 나열된 전환 카테고리 (세 가지 특정 카테고리)는 상호 배타적입니다 *. 표준은 그냥 저에게 약간 회색을 읽습니다. (아니면 처음에는 읽지 않을 것입니다.) – WhozCraig

+1

@WhozCraig 아니요, 그들은 각각 하나씩, 하나, 둘 또는 모두 세 가지 순서로 이루어집니다. 는 포괄적이다. aschepler의 예제를 사용하면 : void f (const int *); int my_array [10]; f (my_array);'배열을 포인터로 변환 한 다음'const' 포인터를 가리키는 포인터로 변환합니다. –

+0

그래, 표준은 철자를 쓰지 만 (즉, 하나의 전환이 채워지면 목록을 백업 할 필요가 없으며 단지 내려갈 수 있습니다.) – WhozCraig

0

keyworkd nullptr 때문에 여러 정의는 C NULL 11 ++ C에 도입하고, INT NULL 인자와 함께 함수의 과부하 때 혼동된다. 성경은 C++ 프로그래밍 언어 (4)에서

#define NULL 0 
#define NULL (void*)0 

, 페이지 270

포인터 - 투 - 부울 변환 조건에 유용하지만, 다른 곳에서 혼란이다.

그래서 나는 nullptr_t varible 변환은 그것이 존재하는 이유이기 때문에 허용되지 않습니다 int로 생각하지만, 그것은 부울 변수와 같은 테스트 조건으로 사용할 수 있습니다.

관련 문제