'const'에 해당되는 글. 2건

  1. 2010/07/30 [C++0x] r-vaule reference: 파라미터의 const 속성 없애기!? (1)
  2. 2008/06/30 C++에서 const char** (2)

 C++ 표준 문서 N2798의 14.3.1의 4번째 항목을 보면. 위와 같은 내용이 있다.
 ( 더 최신 문서인 N3092 에는 위 항목이 빠져 있음. )

 해석을 해서 옮기고 싶지만..
 괜히 혼란만 가중 시킬것 같아서.. 패스하고..

  아무튼 자세히 보면.. 정말 해괴망측한 부분이 있는데
  그 부분을 조금 더 살펴 보자면... 아래와 같은 코드가 있다고 했을 때

    1 template<typename T>

    2 struct X

    3 {

    4     static void f(const T& t)

    5     {

    6         t.a = 100;

    7     }

    8 };

 
 함수 f()는 const로 받은 변수의 값을 변경하고 있다.
 얼핏 보아도 이상한 코드다.
 (  아직 template가 instantiation이 되지 않아서 이 부분만 가지고는 컴파일 에러가 나지 않는다.)


 코드를 조금 더 작성해 보면..

    9 struct S

   10 {

   11     int a;

   12 };

   13 

   14 int main(int argc, char* argv[])

   15 {

   16     S s;

   17     X<S>::f(s);

   18 


이제 아마 Line 17에서 readonly인 a에 값을 넣으려고 했다고 해서 컴파일 에러가 날 것이다.
근데 C++0x 부터는 이를 회피할 수 있는 아주 간단한 방법이 생겼다.
단순히 ' & ' 하나만 추가 하면 된다.


   16     S s;

   17     X<S&>::f(s);

   18 

   19     cout << s.a << endl;


 이제 함수 f()는 
 void X::f(S& t) 와 같이 파라미터의 타입이 정해지고, const 속성을 날려버리게 된다. 우왕ㅋ굳ㅋ
 ( 물론, 이렇게 만들어서 const 속성을 없애서 쓰자는 이야기는 절대 아님...)



 C++의 복잡도는.. 날이 갈 수록 올라가고 있다.


끝으로 Quiz..
각각 파라미터 타입은 어떻게 될까요? ( Line 11 ~ Line 29 )
참고로 gcc 4.5.0과 VS2010 에서 둘다 돌려봤는데. 같게 나왔습니다.

    1 template<typename T>

    2 struct R

    3 {

    4     static void A(T&){}

    5     static void B(const T&){}

    6     static void C(T&&){}

    7     static void D(const T&&){}

    8 };

    9 

   10 {

   11     R<int&>::A(?)

   12     R<int&>::B(?)

   13     R<int&>::C(?)

   14     R<int&>::D(?)

   15 

   16     R<const int&>::A(?)

   17     R<const int&>::B(?)

   18     R<const int&>::C(?)

   19     R<const int&>::D(?)

   20 

   21     R<int&&>::A(?)

   22     R<int&&>::B(?)

   23     R<int&&>::C(?)

   24     R<int&&>::D(?)

   25 

   26     R<const int&&>::A(?)

   27     R<const int&&>::B(?)

   28     R<const int&&>::C(?)

   29     R<const int&&>::D(?)

   30 }



Posted by U_Seung

EC++ 에 보면 const에 대한 설명이 잠깐 나온다.

설명을 보면..

1. char* a;
2. const char* a;
3. char* const a;
4. const char* const a;

위의 넷이 다른 타입이라는 것을 설명하고 있다.

그렇다면.. 간혹 볼 수 있는 const char** 는  어떤 타입일까?

5. const (const char*)*
6. const (char *)*
7. (const char*)*


일단 5,6,7 중의 하나라고 생각할 수 있겠다.
5,6,7의 차이는 어떤 곳에 const의 속성이 붙느냐에 따라서 명확히 다른 type이다.

그렇다면....
- const char**은 5,6,7 중 어떤 타입일까?
- 셋 중에 하나라면 다른 두 가지는 어떻게 표현해야 할까?

이런 의문점이 생기게 만드는 const char** 표현은 그다지 바람직한 모양은 아닌 것 같다.

일단 정답은 7번
const char**는 (const char*)* 이다.
사용법은 아래와 같다.

char* pc = new char[20];
const char* cpc = new char[20];

const char** cppc;
cppc = &pc; // (X) error: invalid conversion from 'char**' to 'const char**'
cppc = &cpc;
*cppc = pc;
*cppc = cpc;
**cppc = '1'; // (X) error: you cannot assign to a variable that is const

 char** ppc = cppc; // (X) error: invalid conversion from 'const char**' to 'char**'


유의 깊게 볼 점은..
char** 와 const char** 은 상호 conversion이 안 된다는 점인데
char*는 const char*로 conversion이 된다는 점에서 차이가 있음을 알고 있을 필요가 있다.



그렇다면 5, 6번의 타입을 만들고 싶다면 어떻게 해야 할까?
방법 중 하나는 typedef를 쓰면 된다.

typedef char* PCHAR;
typedef const char* CPCHAR;

const PCHAR* a;
const CPCHAR* a;




 

Posted by U_Seung
TAG C++, char**, const, CPP