세상은 나를 힘들고 괴롭게 해도 너희들은 항상 나를 즐겁게 하는구나.. ㅡ_ㅡ;;
근데 회사에서 방화벽을 막아 놨다능...
UI가 많이 달라졌습니다.
또 많이 무겁고...
장점은.....음......
C++0x조금 지원하고 PPL 조금 해볼수 있다는거?? ,,,,
소스코트 창에서 CTRL+스크롤하면 축소 확대 되는 기능이 있습니다. ^_^
이...뭥미??
故 노무현 전 대통령님의 서거
많은 사람들이 슬퍼하고 분노 하고 있습니다.
유일한 서민을 위한 대통령, 깨끗한 대통령..
그를 시기하고 괄시하는 자들의 괴롭힘에 세상을 떠나셨습니다.
고인의 명복을 빕니다.
"우리아이들에게 결코 불의와 타협하지 않아도이게 실현 될까요?
성공할수 있다는 하나의 증거를 꼭 하나 남기고
싶었습니다"
절대로 잊지 맙시다..
조갑제, 이장춘, 김동길 이들이 한 망언을 절대 잊지 맙시다.
Rvalue References: C++0x Features in VC10, Part 2
위의 글을 번역한 글입니다.
C++0x에서는 rvalue reference라고 하는 새로운 참조 타입을 제공합니다.
문법은 타입&& 과 const 타입&& 로 선언을 합니다.
최근 표준화 작업중인 문서, N2798 8.3.2/2에서는 : “& 기호를 이용해 lvalue 참조 타입으로 선언하고, && 기호를 이용해 rvalue참조 타입으로 선언합니다. Lvalue 참조 타입과 Rvalue 참조 타입은 참조의 의미만 같지 서로 다른 구문입니다.”
lvalue참조와 rvalue 참조는 초기화 될 때 와 overload resolution 에서 다르게 동작합니다. Lvalue 참조와 Rvalue 참조는 “무엇을 바인드 하려고 하는가?” (i.e. 초기화) 와 “무엇이 바인드 lvalue참조와 Rvalue참조 타입으로 바인드 될것인가?” (i.e. overload resolution로 구분 될 수 있습니다. :
초기화 될때에 따른 구분.:
Lvaule 참조와 Rvalue 참조가 초기화 될 때, const/non-const일 때 바인드 될수 있는 타입을 아래 표에서 확인 할 수 있습니다.
( -> : 바인드 가능함.)
|
|
Lvalue |
Const Lvalue |
Rvalue |
Const Rvalue |
|
Lvalue Reference-> |
O |
X |
X |
X |
|
Const Lvalue Reference -> |
O |
O |
O |
O |
|
Rvalue Reference -> |
O |
X |
O |
X |
|
Const Rvalue Reference -> |
O |
O |
O |
O |
표에서 보이는 문법은 아래 두 규칙에 의해 정해 집니다.:
· const의 의미인 “변경할수 없는 상수” 의 의미 그대로, const가 아닌 참조 타입의 값이 const 인 참조 타입의 값으로 바인드 될수 없습니다.
· non-const lvalue 참조가 non-const rvalue로 바인딩 되어 임시적인 값을 변경할수 없습니다.
각각의 경우에 대한 샘플 코드 입니다. :
|
#include <iostream> #include <string> using namespace std; using namespace std::tr1; string modifiable_rvalue() { return "cute"; } const string const_rvalue() { return "fluffy"; } int main() { string modifiable_lvalue("kittens"); const string const_lvalue("hungry hungry zombies"); string& a = modifiable_lvalue; // Line 18 string& b = const_lvalue; // Line 19 - ERROR string& c = modifiable_rvalue(); // Line 20 - ERROR string& d = const_rvalue(); // Line 21 - ERROR const string& e = modifiable_lvalue; // const lvalue참조가 lvalue를 참조 const string& f = const_lvalue; // const lvalue참조가 const lvalue를 참조 const string& g = modifiable_rvalue(); // Line 23 const string& h = const_rvalue(); // Line 24 string&& i = modifiable_lvalue; // Line 26 string&& j = const_lvalue; // Line 29 - ERROR string&& k = modifiable_rvalue(); // Line 28 string&& l = const_rvalue(); // Line 31 - ERROR const string&& m = modifiable_lvalue; // Line 31 const string&& n = const_lvalue; // Line 32 const string&& o = modifiable_rvalue(); // Line 33 const string&& p = const_rvalue(); // Line 34 } |
Visual Studio 2010 컴파일 메시지 :
|
1>------ Build started: Project: MoveSemantics, Configuration: Debug Win32 ------ 1>ClCompile: 1> main.cpp 1>d:\programming\movesemantics\main.cpp(19): error C2440: 'initializing' : cannot convert from 'const std::string' to 'std::string &' 1> Conversion loses qualifiers 1>d:\programming\movesemantics\main.cpp(21): error C2440: 'initializing' : cannot convert from 'const std::string' to 'std::string &' 1> Conversion loses qualifiers 1>d:\programming\movesemantics\main.cpp(29): error C2440: 'initializing' : cannot convert from 'const std::string' to 'std::string &&' 1> Conversion loses qualifiers 1>d:\programming\movesemantics\main.cpp(31): error C2440: 'initializing' : cannot convert from 'const std::string' to 'std::string &&' 1> Conversion loses qualifiers 1>FileTracker : warning : Attempt to load UI satellite dll from C:\WINDOWS\Microsoft.NET\Framework\v4.0.20409\1042\FileTrackerUI.dll failed. 1>FileTracker : warning : Attempt to load UI satellite dll from C:\WINDOWS\Microsoft.NET\Framework\v4.0.20409\1042\TrackerUI.dll failed. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== |
Rvalue Reference가 도입됨으로써, Rvalue 참조 값이 Rvalue 참조값으로 바인드 될수 있게 되었습니다. 즉, 임시적인 값을 변경할수 있게 된것입니다.
RValue 에 대해 알아 보겠습니다.
흔히들 Lvalue를 대입 연산자 왼쪽에 있는 값, RValue를 대입 연산자 오른쪽에 있는값으로 알고 있는 사람이
많습니다.
C에서는 이 개념이 맞지만 C++ 98/03에서는 약간 다른 개념으로 사용됩니다.
마이크로 소프트 Visual C++ 팀블로그에 있는 내용을 번역해서 올립니다.
원본 : http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx
C++ 98/03에서의 lvalues 와 rvalues
C++ 0x에서 rvalue reference를 이해 하기 위해서는 C++ 98/03에서 lvalue와 rvalue에 대해 먼저 이해 해야 합니다.
"lvalue" 와 "rvalue" 용어는 얘네들의 역사가 복잡해서 이해하기 어렵습니다.
(그런데, 얘네들을 한 단어로 되어 있지만, 발음을 할땐 "L values(엘 밸류스)" and "R values(알 밸류스)"로 발음합니다. <그래서 뭐 어쩌라구연?>), 이들 개념은 C에서부터 나왔고, C++에서 좀더 명확 해졌습니다. 시간을 절약하기 위해서 이들이 왜 “lvalues”와 “rvalues”로 이름 붙여졌는지에 관한 역사 이야기는 넘어가고 C++ 90/03에서 이들이 어떻게 동작하는지에 대한 이야기를 하겠습니다.
(대단한 비밀은 아니지만 “L”은 “left”를, “R”은 “right”를 의미 합니다. 하지만 이 개념은 이름이 정해진 후 진화 해서 위에서 말한 단순한 “left(왼쪽)”, “right(오른쪽)”을 의미 하지 않습니다. 전체적인 역사 강좌를 하기 보단 물리학 에서 사용되는 상위 소립자(up quark)나 하위 소립자(down quark)같은 위성과 같은 의미로 이해 해도 됩니다.<이해하지 말라는 얘기죠? ㅡ_ㅡ;;;>)
C++03 3.10/1 에서: "모든 표현식은 lvalue 나 rvalue를 가진다. “Every expression is either an lvalue or an rvalue." 객체(Object)의 이름이 아닌 lvalue 대(Vs.) rvalue는 표현식의 특성(property) 이라는것을 알아 두어야 합니다.
Lvalues로 선언된 객체(Object)는 단일 표현식을 넘어 서서도 존재 하게 됩니다. 예를 들어 , obj , *ptr , ptr[index] , ++x 들은 lvalue입니다.
Rvalue는 임시적으로 표현식이 끝나면 없어지는 값들입니다.
예를 들어 1729 , x + y , std::string("meow") , x++ 들은 rvalue입니다.
|
CString str; str = _T(“abc”); int i=0; ++i; i++; //위 에서 볼드체로 된 값은 lvalue, 주황색 기울임체로 된 값은 rvalue 입니다. |
++x와 x++와의 차이점을 알아야 합니다. int x=0으로 선언된 x가 있으면 , x는 lvalue이고, 영속성있는 객체 입니다.
++x 도 lvalue가 됩니다. 값을 증가 시키고 영속성있는 객체로 이름을 붙이기 때문 입니다. 하지만 x++는 rvalue입니다. x++는 영속성있는 객체의 원래 값을 복사하고, 영속성 있는 개체의 값을 증가 시키고 복사된 값을 리턴하는 동작을 하기 때문입니다. 여기서 복사된 값은 임시적인 값입니다.
++x 와 x++ 둘다 x의 값을 증가 시키지만, ++x는 영속성있는 객체 자신을 리턴 하지만 x++는 임시적인 복사본을 리턴 합니다.
이것이 ++x가 lvalue고 x++가 rvalue인 이유 입니다.
Lvalue 대 Rvalue 는 표현식이 무슨 동작을 하는지 신경 쓰지 않고
표현식의 이름이 무엇인지에 따라 결정이 됩니다. (뭐가 영속되고 뭐가 임시적인지..)
좀더 직관적으로 이해하길 원한다면, 표현식에서 값의 주소를 가지고 있는지를 알아 보면 lvalue인지 아닌지 알수 있습니다. 만약 값의 주소를 알수 있다면 그 값은 lvalue입니다.
예를 들어 &obj , &*ptr , &ptr[index] , and &++x 같은 표현식은 (문법적으로)유효 합니다. (몇 개의 표현식은 엉망이지만..) 하지만, &1729 , &(x + y) , &std::string("meow") , &x++ 같은 표현식은 (문법적으로)유효하지 않습니다.
왜 이럴까요?
주소연산자(&)에서 피연산자는 lvaue여야 합니다. (C++03 5.3.1/2).
왜냐하면, 영속적인 객체의 주소를 가지는 것은 괜찮지만, 임시적인 객체의 주소를 가지는 것은 굉장히 위험 하기 때문입니다.
앞에서 본 예제는 연산자 오버로딩을 지나 쳤습니다.
"결과 값의 타입이 참조타입(reference)이면 함수 호출은 lvalue 입니다. (C++03 5.2.2/10) 그래서 아래 코드에서
|
vector<int> v(10, 1729); v[0]; |
v[0] 같은 표현식은 []연산자 오버로딩에 의해 int& 를 리턴 하기 때문에 lvalue 입니다.
(그리고 &v[0] 는 유효하고 편리한 표현식입니다.)
하지만 아래 코드에서 s+t는 operator+() 연산자 오버로딩 함수는 string을 리턴하기 때문에 rvalue 입니다. (그리고 &(s+t) 같은 표현식은 유효하지 않습니다.)
|
string s("foo"); string t("bar"); s + t; |
Lvalue나 rvalue 둘다 const 이거나 non-const 일수 있습니다.
아래의 예제를 보세요:
|
string one("cute"); const string two("fluffy"); string three() { return "kittens"; } const string four() { return "are an essential part of a healthy diet"; } one; // 변경 가능한(non-const)lvalue two; // 변경 불가능한(const) lvalue three(); // 변경 가능한(non-const) rvalue four(); // 변경 불가능한(const) rvalue |
[데이터 타입]& 는 변경 가능한 lvalue로 바인딩 됩니다. (그리고, 변수를 관찰 하거나 변경할수 있습니다. )
Const 타입의 변수의 규칙에 어긋나게Const lvalue로 바인드 될수 없습니다.
|
class Foo { private: basic_string<TCHAR> foo_name; public: Foo() { foo_name = _T("default"); } Foo ( basic_string<TCHAR> str) { foo_name = str; } const basic_string<TCHAR>& GetFooName() const { return foo_name; } }; …. Foo f(_T("test")); const basic_string<TCHAR>& str = f.GetFooName(); //정상 basic_string<TCHAR>& str = f.GetFooName(); //<-에러.. |
Rvalue로 바인드 되게 하는건 굉장히 위험합니다. 순간적으로 임시로 사용되는 값을 변경하는 것은 굉장히 큰 버그를 발생하기 때문에 C++에서는 이것을 금기시 하고 있습니다. (VC에서는 이것을 확장하여 사용할수 있습니다. /W4 컴파일 옵션을 사용하면 경고를 주게 됩니다. ) 그리고 const rvalue를 바인드 하는건 이중으로 위험한 짓입니다. (template argument deduction 을 이야기 하는 것이 아닙니다.)
const Type& 은 모든 데이터 값에 바인드 됩니다. : lvalue, const lvalue, rvalues, const rvalues (값을 지켜볼 때 사용됩니다.)에 바인드 될수 있습니다.
Reference(참조) 는 단순한 이름입니다. 그래서 rvalue로 바인드 되었다는 것은 rvalue에 바인딩된 lvalue 입니다. (const 참조(reference)만 rvalue로 바인드 될수 있습니다. 즉, rvalue로 바인드 된 const 참조 타입은 const lvalue일 것입니다.) 조금 혼란 스럽지만 다음에 더욱 정확하게 이야기 하겠습니다. void observe(const string& str)라는 함수가 있을때, observe()함수 내부 구현에서는 str은 const lvalue이고 그 주소는 observe함수가 리턴하기 전까지 사용할 수 있습니다.
observe()함수가 위 예제에서 three()나 four()함수 처럼 rvalue로 호출 되었어도 str은 const lvalue입니다.
observe("purr")가 호출 되어도, 임시로 string 객체를 생성하여 const str에 바인드 됩니다. 위의 예제에서 three()나 four()함수는 이름이 없는 값을 리턴하므로 rvalue인 것입니다. 하지만 observe()함수에서는 str이 이름이기 때문에 lvalue가 되는 것입니다.
위에서도 얘기했듯이 “lvalue 대 rvalue는 표현식에대한 특성이지 객체에 대한 특성이 아닙니다.”( "lvalueness versus rvalueness is a property of expressions, not of objects")<<사실 무슨의미 인지 모르겠네요.>>.
str은 곧 사라질 임시 값에 바인드되지만, str의 주소는 observe() 함수가 리턴이 될때까지 보존이 되기 때문에 lvalue가 되는 것입니다.


