캐스팅을 사용할 때마다 결과 객체는 const 객체입니까?C++로 const 객체 생성하기
... 따라서 함수가 const 개체로 함수를 받아들이면 함수의 인수로만 사용할 수 있습니까?
class C1 {
public: C1(int i=7, double d = 2.5){};
};
void f(C1& c) {};
int main(){
f(8);
return 1;
}
//won't compile
캐스팅을 사용할 때마다 결과 객체는 const 객체입니까?C++로 const 객체 생성하기
... 따라서 함수가 const 개체로 함수를 받아들이면 함수의 인수로만 사용할 수 있습니까?
class C1 {
public: C1(int i=7, double d = 2.5){};
};
void f(C1& c) {};
int main(){
f(8);
return 1;
}
//won't compile
(F (...)의 값만큼의 인수를 수신하면 당연히 그 그것이 작동 할 수있는 비 CONST 버전 을 얻는다) 보통 때 특정 유형의 객체 다른 형식의 개체 (비표준 형식)로 변환되면 임시 개체가 만들어집니다 (const 개체가 아님). 임시 객체 (invisible, nameless, rvalue)는 (C++ 98/03에서) const 인 참조 ('예외 객체'라고 알려진 임시 참조 제외)에만 바인딩 할 수 있습니다. 따라서 임시를 만드는 변환 결과는 const 참조 또는 복사/변환 할 수있는 형식으로 받아들이는 함수의 인수로만 사용할 수 있습니다.
예 :
void f(double); // 1
void f(const int&); // 2
void f(int&); // 3
struct B { B(int) { } };
struct C { C(int) { } };
void f(B b); // 4
void f(B& b); // 5
void f(const C& c); //6
void f(C& c); // 7
// D inherits from B
struct D : B { D(int) : B(0) { } };
void f(D& d); // 8
int main()
{
f((int) 3.0); // calls 2, NOT 3
f((float) 3); // calls 1 - const reference requires the same type
f(1); // calls 2, NOT 3
f((B) 1); // calls 4, not 5 - can accept it by non-const value
f((C) 1); // calls 6, not 7 - can accept it by const-reference
f((D) 1); // calls 4, not 8 - since a 'D' temporary object can be converted to a 'B' object - but will not bind to a non-const reference
}
희망이 있습니다.
당신은 다시 작성할 수 있습니다과 :
class C1
{
public: C1(int i=7, double d = 2.5){};
};
void f(C1& c){};
int main()
{
C1 c(8); //named
f(c);
//... can access the modified C1 instance here ...
return 1;
}
버전에 대해 좋아하지 않는 컴파일러가 C1
인스턴스가 있다는 것을 것은 이름이 지정되지 않은 일시 : 그것 때문에 (수정되는 f
하지만, 컴파일러는 호출자 (main
)가 이러한 수정을 수신/보존/통지 할 방법이 없다는 것을 알고 있습니다.
'캐스팅'이라고 하기엔 다소 벗어났습니다. 당신은 '암시 적 건설'을하고 있습니다. 암시 적 생성은 항상 임시 객체를 만듭니다. 임시 객체는 항상 const입니다.
생성자를 '명시 적'으로 표시 할 수 있습니다. 그러면 여기에 표시되는 암시 적 생성 통화가 차단됩니다. 그러나 이것은 f (8) 대신에 f (C (8))가 필요하다는 것을 의미합니다. 임시 인스턴스이기 때문에 C 인스턴스는 여전히 const가 될 것입니다. 그러나 캐스트는 수행되지 않습니다.
정말로 필요한 경우 더러운 해결 방법은 const_cast를 참조하십시오. 다른 해결 방법은 두 개의 라이너를 수행하는 것입니다. C c (8); f (c);
+1 : 나는이 대답을 좋아합니다. 따라서 각 전환의 순위와 종류를 지정하는 것이 유용 할 수 있습니다 (특정 버전이 다른 버전보다 왜 선택되었는지 보여주기 위해). 내가 옳다는 것을 확인해주세요. - 첫 번째 호출 (A) : 2 로의 완전 일치, 1 로의 변환 (B) 1로 승격, 2로 변환, (C) 2에서 완전 일치, 다음으로 변환 : A, B, C, 1. (D) 완전 일치 4. (E) 완전 일치 6. (F) 변환 (유도 -> 기본) - 4. 'const T'및 'T'의 모든 참조 바인딩에서 'const T'는 최상위 레벨의 const로 간주되어 rank (void f (T); void f (const T); f (T());'ambiguous)에 영향을 미치지 않습니다. –
예. 바로 당신의 전환과 순위의 붕괴에 - 우리가 여기에서 다루었 기 때문에 또는 http://stackoverflow.com/questions/1092714/conversion-precedence-in-c/1092724#1092724, 나는 너무 많은 것에 집중하고 싶지 않았다. 오버로드 해결 -하지만 임시에 바인딩 할 수 있습니다 - 아마도 내가 다른 함수 이름을 사용해야하고 그것을 더 간단하게 보관해야합니까? –
아, 알겠습니다. 나는 더 나은 것이 무엇인지 모른다. 그러나 나는 그것이 현재 어떻게 그것을 좋아한다.특정 버전이 특히 선호되는 이유를 알고 싶다면 다른 답변을 읽고 댓글 섹션을 살펴볼 수 있습니다. –