0

은 내가 vector 있습니다. 그러나 단지 개인 운동을 위해 나는 멋진 C++ 스타일로이 작업을 수행하려면, 그래서 대신 std::vector<const island*> p_sea의 I는 입력 :한 벡터의 요소에 대한 참조를 다른 벡터에 복사하는 방법은 무엇입니까?</p> <pre><code>std::vector<island> sea; </code></pre> <p>그리고 지금은 또 다른 <code>vector</code>이 <code>vector</code>의 모든 요소에 대한 포인터를 개최 할 :

std::vector<std::reference_wrapper<const island>> r_sea; 

을 그리고 지금은 참조가이 새로운 vector 채울 싶습니다

std::transform(sea.begin(), sea.end(), 
       std::back_inserter(r_sea), 
       std::cref<island> 
); 

내가 이해하는 방법은 cppreference 기사에서 transform의 네 번째 인수는 소스 범위의 요소에 대한 const 참조를 가져 와서 대상 범위의 요소를 반환하는 함수 여야합니다. 이것은 정확히 std::cref<island>입니다. 인수로 const island&을 취하고 std::reference_wrapper<const island>을 반환합니다. 그래서 나는 이것이 효과가 있어야한다고 생각하니 ??

하지만, 그렇지 않습니다 다음 컴파일 오류에

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <functional> 
#include <iterator> 


struct island { 
    long long x,y; //coords 
}; 

int main() { 
    std::vector<island> sea; 
    std::vector<std::reference_wrapper<const island>> r_sea; 

    std::transform(sea.begin(), sea.end(), 
        std::back_inserter(r_sea), 
        std::cref<island> 
    ); 

    return 0; 
} 

이 결과 :

prog.cpp: In function ‘int main()’: 
prog.cpp:19:5: error: no matching function for call to ‘transform(std::vector<island>::iterator, std::vector<island>::iterator, std::back_insert_iterator<std::vector<std::reference_wrapper<const island> > >, <unresolved overloaded function type>)’ 
    ); 
    ^
In file included from /usr/include/c++/6/algorithm:62:0, 
       from prog.cpp:3: 
/usr/include/c++/6/bits/stl_algo.h:4166:5: note: candidate: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) 
    transform(_InputIterator __first, _InputIterator __last, 
    ^~~~~~~~~ 
/usr/include/c++/6/bits/stl_algo.h:4166:5: note: template argument deduction/substitution failed: 
prog.cpp:19:5: note: could not resolve address from overloaded function ‘cref<island>’ 
    ); 
    ^
In file included from /usr/include/c++/6/algorithm:62:0, 
       from prog.cpp:3: 
/usr/include/c++/6/bits/stl_algo.h:4203:5: note: candidate: template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation) 
    transform(_InputIterator1 __first1, _InputIterator1 __last1, 
    ^~~~~~~~~ 
/usr/include/c++/6/bits/stl_algo.h:4203:5: note: template argument deduction/substitution failed: 
prog.cpp:19:5: note: could not resolve address from overloaded function ‘cref<island>’ 
    ); 

https://ideone.com/E80WXH

내가 잘못 뭐하는 거지?

... 나는 사악한 C 포인터로 돌아왔다.

+1

'std :: reference_wrapper '대신'std :: reference_wrapper '를 사용해보십시오. – cdhowie

+0

@cdhowie 오타; 컴파일 오류를 수정하지 않습니다. 지금 질문에서 오타를 제거하고 있습니다. – gaazkam

+0

문제는'std :: cref'가 오버로드되었다는 것입니다. 어떤 오버로드를 사용해야하는지 명확하게해야합니다. – StoryTeller

답변

1

std::cref에 과부하가 걸립니다. 템플리트 아규먼트를 지정하는 것만으로는 오버로드 사이를 불분명하게하는 것만으로는 충분하지 않습니다. 펑터 개체 (람다)에

  1. 캐스트는

    static_cast<std::reference_wrapper<const island>(*)(const island&)>(std::cref<island>) 
    
  2. 들어 올려 이름을 : 당신은 두 가지 옵션이 있습니다. @ 야크처럼 제안했다.

4

std::cref<island>[](auto&x){return std::cref<island>(x);}으로 바꾸고, 이라고 가정합니다.

에서 autoisland const으로 바꿉니다.

cref에 오버로드가있는 경우 오버로드 집합이 개체가 아니므로 오버로드 집합을 개체로 전달할 수 없습니다.