2014-10-24 4 views
1

아래 코드에서 인수를 전달할 때 왜 std::forward을 사용해야합니까?std :: forward를 사용해야하는 이유는 무엇입니까?

class Test { 
    public: 
    Test() { 
     std::cout << "ctor" << std::endl; 
    } 
    Test(const Test&) { 
     std::cout << "copy ctor" << std::endl; 
    } 
    Test(const Test&&) { 
     std::cout << "move ctor" << std::endl; 
    } 
}; 

template<typename Arg> 
void pass(Arg&& arg) { 
    // use arg.. 
    return; 
} 

template<typename Arg, typename ...Args> 
void pass(Arg&& arg, Args&&... args) 
{ 
    // use arg... 
    return pass(args...); // why should I use std::forward<Arg>(args)... ? 
} 

int main(int argc, char** argv) 
{ 
    pass(std::move<Test>(Test())); 

    return 0; 
} 

std::forward이 있거나없는 코드에는 복사/이동이 나타나지 않습니다.

+1

관련; http://stackoverflow.com/questions/3582001/advantages-of-using-forward – Niall

+2

http://stackoverflow.com/questions/7257144/when-to-use-stdforward-to-forward-arguments – Drax

+0

3834459 두 개의 게시물 위에 혼란스러워 하시겠습니까? 아니면 그들이 당신의 문제에 대답합니까? – Yakk

답변

5

std::forward에는 무엇이 좋은지, 어떤 방식으로 작동하는지 (예 : herehere)가 있습니다.

간단히 말해 은 인수의 값 카테고리을 보존합니다. 완전한 전달은 함수에 제공된 인수가 originally provided과 같은 값 범주 (기본적으로 r 값 대 l 값)를 갖는 다른 함수 (또는 함수 내에서 사용됨)로 전달되도록 보장합니다. 일반적으로 reference collapsing이 발생했을 수도있는 템플릿 함수 (범용/전달 참조 포함)와 함께 사용됩니다.

아래 코드 샘플을 고려하십시오. std::forward을 제거하면 requires lvalue이 인쇄되고 std::forward을 추가하면 requires rvalue이 출력됩니다. func은 rvalue인지 lvalue인지에 따라 오버로드됩니다. std::forward없이 전화하면 잘못된 과부하가 걸립니다. 이 경우 std::forward이 필요합니다. pass이 rvalue와 함께 호출됩니다.

#include <utility> 
#include <iostream> 
class Test { 
    public: 
    Test() { 
     std::cout << "ctor" << std::endl; 
    } 
    Test(const Test&) { 
     std::cout << "copy ctor" << std::endl; 
    } 
    Test(Test&&) { 
     std::cout << "move ctor" << std::endl; 
    } 
}; 

void func(Test const&) 
{ 
    std::cout << "requires lvalue" << std::endl; 
} 

void func(Test&&) 
{ 
    std::cout << "requires rvalue" << std::endl; 
} 

template<typename Arg> 
void pass(Arg&& arg) { 
    // use arg here 
    func(std::forward<Arg>(arg)); 
    return; 
} 

template<typename Arg, typename ...Args> 
void pass(Arg&& arg, Args&&... args) 
{ 
    // use arg here 
    return pass(std::forward<Args>(args)...); 
} 

int main(int, char**) 
{ 
    pass(std::move<Test>(Test())); 
    return 0; 
} 
+0

Test const 및 버전을 잘못 호출하는 이유는 무엇입니까? 내 말은 : 그게 무슨 가격이야? – Dean

+1

@ user3834459 함수의 기능에 따라 다릅니다. 두 가지 오버로드 사이의 기능이 값 범주를 필요로하거나 (또는 ​​최적화 된 경우), 그렇다면 그렇지 않습니다. 일반적으로 두 개의 과부하가 주어지면 약간의 차이가 있다고 가정하고 올바른 버전을 호출하는 것이 좋습니다. – Niall

+0

좋아요, 알겠습니다. 감사! – Dean

관련 문제