Visual Studio 2010 공식 팀 블로그 @vsts2010

Posted by 흥배

RValue Reference에 관한 글의 마지막으로 Perfect Forwarding에 대해서 설명합니다.

 

 

인수 전달 문제

 

< Code 1. >

void inner(int& i)

{

}

 

template <typename T> void outer(T& t) {

           inner(t);

}

 

 

int main()

{

           int a = 5;

           outer(a);

 

           outer(6);

           return 0;

}


<Code 1>을 컴파일 하면 outer(6)에서 컴파일 에러가 발생합니다.

error C2664: 'outer' : cannot convert parameter 1 from 'int' to 'int &'라는 에러 결과가 출력됩니다. <Code 1>을 컴파일 하기 위해서 파라메터에 const를 포함하는 함수를 재정의 해야 합니다.

 


< Code 2. >

void inner(const int& i)

{

}

template <typename T> void outer(const T& t) {

           inner(t);

}

 

<Code 2>에서 정의한 함수를 <Code 1>에 추가하면 <Code 1>은 컴파일 할 수 있습니다.

하지만 함수의 파라메터의 개수가 N개이고 파라메터 중 const를 포함하는 것의 위치가 제각각 이라면 재정의 해야 할 함수가 지수적으로 증가합니다.

그러나 ‘&&’을 사용하면 이 문제를 해결 할 수 있습니다.

 


< Code 3. >

void inner(int& i)

{

}

 

template <typename T> void outer(T&& t) {

           inner(t);

}

 

int main()

{

           int a = 5;

           outer(a);

 

           outer(6);

           return 0;

}

 

 


 

std::forward

 

< Code 4. >

class MyTest

{

public:

           MyTest(int& N) {}

};

 

template <typename T1, typename T2>

std::shared_ptr<T1>

factory(T2&& t2)

{

    return std::shared_ptr<T1>( new T1( t2 ) );

}

 

int main()

{

           std::shared_ptr<MyTest> p1 = factory<MyTest>(5);

          

           int value = 5;

           std::shared_ptr<MyTest> p2 = factory<MyTest>(value);

 

           return 0;

}

 

<Code 4>에서도 <Code 3>과 같이 RValue Reference에 의해

std::shared_ptr<MyTest> p1 = factory<MyTest>(5);

에서 컴파일 에러가 발생하는 것을 해결했습니다.

 

그런데 이것은 MyTest(int& N) 에서 LValue 전달 받기를 원하지만 ‘&&’ 의해서 RValue 전달이 되어버려 Perfect Forwarding이 파괴되어 버렸습니다.

이런 문제를 해결하기 위해서는 std::forward를 사용하면 됩니다.

 

< Code 5. >

template <typename T1, typename T2>

std::shared_ptr<T1>

factory(T2&& t2)

{

    return std::shared_ptr<T1>( new T1( std::forward<T2>(t2) ) );

}

 

Factory 함수를 <Code 5>와 같이 바꾼 후 컴파일을 하면

MyTest::MyTest(int &)' : cannot convert parameter 1 from 'int' to 'int &'

라는 에러가 출력됩니다.

 

 

 

이것으로 생각외로 길었던 RValue Reference에 대한 글을 마칩니다.


서두에 이야기 했듯이 RValue Reference C++에 있어서 아주 유용한 것이지만 정확하게 이해하기가 쉽지 않습니다. Microsoft VC++ 팀에서도 우선은 RValue Reference의 사용 패턴에 대해서 이해하도록 권하고 있습니다. 그래서 저도 사용 패턴에 맞추어 글을 적었습니다.


RValue Reference에 대해서 자세하게 알고 싶은 분들은 앞선 글에서 소개했던 사이트를 다시 소개 해 드릴 테니 꼭 읽어보시기 바랍니다.

 

 

 

참고 사이트

1. Rvalue References: C++0x Features in VC10, Part 2

http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx

 

2. A Brief Introduction to Rvalue References

http://www.artima.com/cppsource/rvalue.html


저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

댓글을 달아 주세요

  1. template을 지우고 T를 int로 쓰면 에러가 나네요... 꼭 템플릿을 써줘야 하는 이유가 있나요?

  2. 질문... 2010/08/30 11:04

    1.
    void func(int&& rval)

    2.
    template<typename T>
    void func(T&& rval)


    int i = 0;
    func(i);

    1번은 에러가나는데 2번의 경우 에러가 나지 않습니다.
    에러가 나지 않는 이유를 설명해 주실 수 있으신가요?