2009-05-15 9 views
23

최근 답변에 대한 여러 의견 (What other useful casts can be used in C++)은 C++ 변환에 대한 나의 이해가 잘못되었음을 암시합니다.C++ 암시 적 변환

#include <string> 

struct A { 
    A(const std::string & s) {} 
}; 

void func(const A & a) { 
} 

int main() { 
    func("one");     // error 
    func(A("two"));   // ok 
    func(std::string("three")); // ok 
} 

내 주장은 변환에서있다가 A에 const를 숯불 *로부터의 변환이없는 becauuse하여 첫 번째 함수 호출이 오류가이라고했다 : 그냥 문제를 명확히하기 위해, 다음 코드를 고려 문자열을 A로 변환하지만이 변환을 사용하면 둘 이상의 변환이 포함됩니다. 나의 이해는 이것이 허용되지 않는다는 것이며, 이것은 g ++ 4.4.0 & 코모 컴파일러에 의해 확인 된 것으로 보인다. 꼬모으로, 나는 다음과 같은 오류 얻을 : 내가 잘못 위치를 바람직하게는 C++ 표준을 참조하여, 여기도 또는 원래 대답, 지적 할 수있는 경우

"ComeauTest.c", line 11: error: no suitable constructor exists 
     to convert from "const char [4]" to "A" 
     func("one");     // error 

을 이렇게하십시오.

그리고 C++ 표준의 대답은 것 같다 : Abhay에

At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.

감사 견적을 제공.

+0

답변에 대한 답변에 모두 잘못되었습니다. 죄송합니다. 나는 "과부하 해상도는 호출 할 사용자 정의 변환을 선택하는 데 사용됩니다."라고 말했고 나는 자신에게 다음과 같이 A (string const &)를 해결하고 "one"을 전달하지만 완전히 실패했습니다. 13.3.3.1.2는 "사용자 정의 변환 시퀀스는 초기 표준 변환 시퀀스 다음에 사용자 정의 변환 (12.3)이 이어지는 두 번째 표준 변환 시퀀스 으로 구성됩니다." 그러나 "one"-> string은 표준 변환 시퀀스가 ​​아니지만 다른 사용자 정의 변환 시퀀스가 ​​필요합니다! –

+0

그냥 내 대리석을 잃지 않을만큼 오래 :-) –

+0

큰 질문입니다! 이 토론은'std :: string'은 언어의 일부가 아니며 그 언어와의 변환은 "사용자 정의"라는 것을 의미합니다. 적어도 그건 내 이해이고, 내가 틀렸다면 나를 바로 잡아라. 질문이 이것에 대해 더 명백한 것이라면 좋을 것입니다. 'std :: string'의 정확한 상태는 오래된 C++ 손에 대해 명료 할 수 있지만, 금세기에 언어에 온 사람에게는 실현하기가 쉽지 않습니다. –

답변

12

나는 sharptooth의 답변이 정확하다고 생각합니다. '변환'이라는 제목의 C++ 표준 (SC22-N-4411.pdf) 섹션 12.3.4에서는 암시 적 사용자 정의 변환이 하나만 허용된다는 것을 분명히합니다.

1 Type conversions of class objects can be specified by constructors and by conversion functions. These conversions are called user-defined conversions and are used for implicit type conversions (Clause 4), for initialization (8.5), and for explicit type conversions (5.4, 5.2.9).

2 User-defined conversions are applied only where they are unambiguous (10.2, 12.3.2). Conversions obey the access control rules (Clause 11). Access control is applied after ambiguity resolution (3.4).

3 [ Note: See 13.3 for a discussion of the use of conversions in function calls as well as examples below. —end note ]

4 At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.

+0

특정 시나리오에서 암시 적 변환을 사용하는 것을 좋아하는 이유를 공유해야합니다. 즉, 변수에 관련된 함수를 수행하는 클래스와 간단한 유형의 변수를 결합하고자 할 때. 암시 적 변환 외에도 std :: string이 c_str()을 제공하는 것과 같은 방식으로 값을 반환하는 클래스의 함수를 제공합니다. 그런 다음 필요한 경우 추가 클래스 기능을 사용할 수 있으며 관련 기능을 함께 유지하면서 어디에서나 매우 가볍게 이동할 수 있습니다. – moodboom

8

암시 적 변환 중 하나만 가능합니다.

변환 연산자와 매개 변수가있는 생성자를 조합하여 두 번의 변환을 수행 할 수 있지만 C4927 warning - "잘못된 변환, 하나 이상의 사용자 정의 변환이 암시 적으로 적용되었습니다."- VC++에서 이유.

5

The C++ Programming Language (4. 에디션.) (섹션 18.4.3)을 말한다 일부는 네이티브 사이에있는 경우 "사용자 정의"부분은 여러 암시 적 변환 같은 소리한다 허용 될 수

only one level of user-defined implicit conversion is legal

유형.

+0

+1에 대한 최신 의견. Stroustrup의 저서 – mloskot

9

이미 합의 된 것처럼 보입니다. 네 말이 맞습니다.

하지만이 질문/답변 아마도 stackoverflow C++ 암시 적 변환에 대한 참조 지점이 될 것입니다. 템플릿 인수에 규칙을 추가하는 것이 좋습니다.

템플릿 인수 공제에 사용되는 인수에는 암시 적 변환을 사용할 수 없습니다. 이것은 꽤 명백하게 보일지도 모르지만 그럼에도 불구하고 미묘한 이상 함으로 이어질 수 있습니다.

적절한 예, 표준 : : 문자열 또한 운영자

std::string s; 
s += 67; // (1) 
s = s + 67; // (2) 

(1) 컴파일하고 잘 작동 operator+=이 멤버 함수 템플릿 문자 매개 변수가 이미 char에의에 대한 std::string을 (인스턴스화하여 추론한다). 따라서 암시 적 전환이 허용됩니다 (int ->char).ASCII에서이 operator+은 무료 기능과 여기 이 공제에 사용되는 템플릿 문자 인수로 선언으로

(2) 컴파일러 오류를 준다 'C'가 될 것입니다.