2013-05-14 2 views
2
// --- Move constructor 
Matrix(Matrix&& other) throw() : data_(other.data_), Rows_(other.Rows_), Columns_(other.Columns_) { other.Rows_ = other.Columns_ = 0; other.data_ = nullptr; } 

// --- Move assignment 
Matrix & operator=(Matrix&& other) throw() { 
    using std::swap; 
    swap(Rows_, other.Rows_); 
    swap(Columns_, other.Columns_); 
    swap(data_, other.data_); 
    return *this; } 

MultiplyAdd 구현 :은 여기에서 복사를 방지하는 의미 체계를 옮깁니 까?

template <class T> 
Matrix<T> MultiplyAdd(const T a,const Matrix<T> &x,const T b) { 
    Matrix<T> out(a*x+b); 
    return out; } 

template <class T> 
Matrix<T> MultiplyAdd(const Matrix<T> a,const Matrix<T> &x,const T b) { 
    Matrix<T> out(a*x+b); 
    return out; } 

int main(){ 
    Matrix<> x = // some initialization 
    auto&& temp_auto = MultiplyAdd(a,x,b); 
    for (int i = 1; i < N-1; i++) { 
     temp_auto = MultiplyAdd(temp_auto,temp2,b); } 
    return 0; 
} 

질문 : 마지막 코드에서 auto 키워드의 사용이 임시 변수의 생성을 피할 것인가? 앞뒤에 'for'루프 내부에서 중요합니다.

+0

''throw() '대신 ['noexcept'] (http://en.cppreference.com/w/cpp/language/noexcept_spec)를 사용하십시오. – 0x499602D2

+0

yhm, 확인. 때문에? –

+0

@gumtree : C++에서 동적 예외 사양이 더 이상 사용되지 않습니다. –

답변

1

마지막 코드 단편에 auto 키워드를 사용하면 임시 생성을 피할 수 있습니까?

아니요. 어쨌든 temp_auto은 참조이므로 임시 작성해야하며 참조가 바운드되어 있어야합니다.

auto temp_auto = MultiplyAdd(a,x,b); 

하는 경우 컴파일러는 복사/이동 생략을 수행 할 수 있고 temp_auto에 직접 MultiplyAdd()의 결과를 생성하지 않고 : 당신이했던 경우

확률이 높은 것이다 임시의 생성을 피하기 위해 이동 생성자를 호출해야합니다.

"확률"에 대해 말하는 이유는 C++ 11 표준의 단락 12.8/31에 따라 컴파일러에서 복사/이동 제거를 수행 할 수는 있지만 의무는 아닙니다.

무슨 일이 일어나고 있는지 명확히하기 위해 컴파일러가 객체를 반환 할 때 수행해야 할 작업을 설명하려고합니다. 이 간단한 기능과 이후의 함수 호출을 고려 : x를 반환 할 때 여기에

X foo() { X x; /* ... */ return x; } 

// ... 

X y = foo(); 

를, 컴파일러는해야 할 것입니다 :

  1. x에서 임시을 이동 - 구성 (의이 t를 호출하자)
  2. 이동 구성물 yt. 생략을 복사 할
  3. 이제

감사는, 컴파일러는, 임시 t의 생성을 방지 y에 직접 반환 된 객체 x를 구성하고, 이동 생성자에 모두 전화를 생략하다 할 수있다. 루프 내부 한편

:

temp_auto = MultiplyAdd(temp_auto,temp2,b); 

당신은 할당을 다하고 있습니다.우리의 간단한 예에서,이하는 것과 동일합니다 : foo()에서 x을 반환 할 때, 심지어 여기

X foo() { X x; /* ... */ return x; } 

// ... 

X y; 
y = foo(); 

, 컴파일러에 있습니다

  1. 호출하자 (foo()에서 x에서 임시을 이동-구성 다시 t);
  2. ty으로 이동 할당하십시오. 무브 할당 연산자 호출 될 수 있지만이 경우에도

는 임시의 생성은 y에 할당하는 움직임 할당 연산자 직접 (대신 t의) x 통과시킴으로써 회피 할 수있다 (복사/이동 생성자의 호출 만 생략 가능).

원본 예제 (temp_auto은 참조)와 위의 수정 된 예에서 모두 마찬가지입니다. 여기서 temp_auto은 클래스 유형의 개체입니다.

+0

확률은? 임시 피할 것인가, 그렇지 않을 것인가? –

+0

@ gumtree : 복사/이동 elision은 컴파일러의 재량에 달려 있습니다. 실제로, 적극적인 최적화를 통해 컴파일러에서 필 요할 확률은 매우 높습니다. 그러나 원칙적으로, 당신의 이동 생성자가 부작용을 가지고있다하더라도 그것은 컴파일러에 달려 있습니다. –

+0

ok, 고맙습니다. –

관련 문제