2017-02-24 10 views
3
예를 들어
#include<iostream> 
#include<utility> 
#include<tuple> 
#include<functional> 
using namespace std; 
int main() 
{ 
    int i = 0; 
    auto p = make_pair(ref(i), ref(i++)); 
    p.first++; 
    p.second++; 
    cout << "i = " << i << endl; 
} 

이 같은 ref()를 사용하는 경우는, 컴파일러는이 왜 삭제 기능을 사용하고 있습니다 '[_Tp = INT와] 무효 표준을 :: REF (const를 _Tp &&)'

use of deleted function 'void std::ref(const _Tp&&) [with _Tp = int]'

을 말할 것이다 내 코드는

#include<iostream> 
#include<utility> 
#include<tuple> 
#include<functional> 
using namespace std; 
int main() 
{ 
    int i = 0; 
    auto p = make_pair(ref(i), ref(++i)); 
    p.first++; 
    p.second++; 
    cout << "i = " << i << endl; 
} 

을 따르고 그러나 만약 성공적으로 출력 i = 3을 얻을 것이다, 그래서 너무 다른 답변을 얻을 이유를 이해할 수 없다.

+12

'ref (i ++)'- 임시 참조,'++ i'는 원래 변수에 대한 참조를 반환합니다. – xinaiz

+0

@BlackMoses : 답변 섹션 _에서 대답하십시오. –

+0

나는 반성 후, 매우 고맙게 생각한다. ref (i ++)가 일시적인 참조가 매우 합리적이라고 생각한다. – Yyh

답변

7

std::ref은 변수를 취해 그 변수에 대한 참조처럼 작동하는 것을 제공합니다.

i++은 변수가 아닙니다. 그것은 일시적이다. 이는 후행 증가가 어떻게 작용했기 때문입니다. 원래 값은 증가하지만 표현식은 이전 값인 값으로 평가되며 읽을 수 있도록 임시 값을 보유해야합니다.

std::ref과 같은 실수를 피하기 위해 임시 사용을 허용하지 않습니다. 그렇지 않으면 매달린 참조 일 것입니다.

++i 다른 한편으로는 원래 변수를 되돌려 놓았으므로 참고 만하면됩니다.

그러나 i++i을 바로 옆에 넣을 수는 없습니다. 두 표현식은 서로에 대해 불확 실한 순서로 배열됩니다. 모든 종류의 비용으로 이러한 종류의 코드를 피하십시오.

+2

나는 순서를 찾았다. C++ 14에서 그것은 순차적 인수 논쟁으로 인한 UB 였지만 C + +17 불확실한 순서로 배열 될 것입니다. 즉,'ref (i)'는'++ i'의 부작용 전후에'i'를 읽을 수 있지만,'++ i'의 부작용은 UB가 아닙니다. 후자는 N4606 현재입니다. [참조] (http://stackoverflow.com/a/39238441/1505939) –

+0

나는이 값이 UB 인 것을 확신하지 못한다. i의 값이 참조를 취하는 하위 식에 사용되지 않았기 때문이다. 그것에. 그러나 일반적인 점은 정확합니다 – Caleth

+0

이 문제는 벡터를 말할 때도 발생합니다 myvec {1,2,3}; ref (myvec [0]). 당신은 얻을 것이다 : 오류 : 삭제 된 함수의 사용 'void std :: ref (const _Tp &&) –