Programing

C ++ 11에서 값별 전달이 합리적인 기본값입니까?

lottogame 2020. 6. 24. 07:56
반응형

C ++ 11에서 값별 전달이 합리적인 기본값입니까?


전통적인 C ++에서는 값을 함수와 메소드에 전달하는 것이 큰 객체의 경우 속도가 느리고 일반적으로 눈살을 찌푸립니다. 대신 C ++ 프로그래머는 참조를 전달하는 경향이 있지만 속도는 빠르지 만 소유권과 특히 메모리 관리 (객체가 힙 할당되는 경우)와 관련된 모든 종류의 복잡한 질문을 유발합니다.

이제 C ++ 11에는 Rvalue 참조와 이동 생성자가 있습니다. 즉, std::vector값으로 전달되거나 함수 외부로 값 이 큰 대형 객체 (예 :)를 구현할 수 있습니다.

따라서 이것이 기본값이 std::vectorand std::string? 와 같은 유형의 인스턴스에 대해 값으로 전달되어야 함을 의미 합니까? 사용자 정의 개체는 어떻습니까? 새로운 모범 사례는 무엇입니까?


본문 내부에 사본을 만들어야하는 경우 합리적인 기본값 입니다. 이것이 Dave Abrahams 가 옹호하는 내용입니다 .

지침 : 함수 인수를 복사하지 마십시오. 대신 값으로 전달하고 컴파일러가 복사를 수행하게하십시오.

코드에서 이것은 이것을 수행하지 않는다는 것을 의미합니다.

void foo(T const& t)
{
    auto copy = t;
    // ...
}

그러나 이것을하십시오 :

void foo(T t)
{
    // ...
}

호출자가 다음 foo과 같이 사용할 수있는 이점이 있습니다 .

T lval;
foo(lval); // copy from lvalue
foo(T {}); // (potential) move from prvalue
foo(std::move(lval)); // (potential) move from xvalue

최소한의 작업 만 수행됩니다. 당신은 참조와 동일한 기능을 수행 할 두 개의 오버로드가 필요 거라고 void foo(T const&);하고 void foo(T&&);.

이를 염두에두고 이제는 다음과 같이 소중한 생성자를 작성했습니다.

class T {
    U u;
    V v;
public:
    T(U u, V v)
        : u(std::move(u))
        , v(std::move(v))
    {}
};

그렇지 않으면 참조로 const전달해도 여전히 합리적입니다.


거의 모든 경우에 의미는 다음 중 하나 여야합니다.

bar(foo f); // want to obtain a copy of f
bar(const foo& f); // want to read f
bar(foo& f); // want to modify f

다른 모든 서명은 드물게 사용하고 정당화해야합니다. 컴파일러는 이제 거의 항상 가장 효율적인 방법으로이 작업을 수행합니다. 코드 작성을 계속할 수 있습니다!


함수 본문 내에서 객체의 사본이 필요하거나 객체 만 이동해야하는 경우 매개 변수를 값으로 전달하십시오. const&객체에 대한 비변이 액세스 만 필요한 경우 통과 하십시오.

객체 복사 예 :

void copy_antipattern(T const& t) { // (Don't do this.)
    auto copy = t;
    t.some_mutating_function();
}

void copy_pattern(T t) { // (Do this instead.)
    t.some_mutating_function();
}

객체 이동 예 :

std::vector<T> v; 

void move_antipattern(T const& t) {
    v.push_back(t); 
}

void move_pattern(T t) {
    v.push_back(std::move(t)); 
}

비 변동 액세스 예 :

void read_pattern(T const& t) {
    t.some_const_function();
}

이론적 근거는 Dave AbrahamsXiang Fan의 블로그 게시물을 참조하십시오 .


함수의 서명은 의도 된 용도를 반영해야합니다. 가독성은 옵티 마이저에도 중요합니다.

이것은 이론적으로 적어도 실제로는 아니더라도 몇 년 안에는 가장 빠른 코드를 생성하기위한 최적화의 전제 조건입니다.

Performance considerations are very often overrated in the context of parameter passing. Perfect forwarding is an example. Functions like emplace_back are mostly very short and inlined anyway.

참고URL : https://stackoverflow.com/questions/7592630/is-pass-by-value-a-reasonable-default-in-c11

반응형