왜 참조 벡터를 만들 수 없습니까?
내가 이것을 할 때 :
std::vector<int> hello;
모든 것이 잘 작동합니다. 그러나 대신 참조 벡터로 만들면 :
std::vector<int &> hello;
나는 끔찍한 오류를 얻는다
오류 C2528 : '포인터': 참조 포인터가 잘못되었습니다
구조체에 대한 많은 참조를 벡터에 넣고 싶습니다. 그래서 포인터로 방해 할 필요가 없습니다. 왜 이것에 대해 벡터가 울화를 일으키는가? 대신 포인터 벡터를 사용하는 유일한 옵션입니까?
벡터와 같은 컨테이너의 구성 요소 유형은 지정 가능 해야합니다 . 참조는 할당 할 수 없습니다 (선언 될 때 한 번만 초기화 할 수 있으며 나중에 참조 할 수는 없습니다). 다른 비 할당 유형은 컨테이너 구성 요소로 vector<const int>
허용되지 않습니다 ( 예 : 허용되지 않음).
예 std::reference_wrapper
, 참조를 모방하지만 할당 가능하고 "재 장착"될 수있는를 찾을 수 있습니다.
본질적으로 참조는 생성 된 시점에만 설정할 수 있습니다. 즉, 다음 두 줄은 매우 다른 효과를 갖습니다.
int & A = B; // makes A an alias for B
A = C; // assigns value of C to B.
또한 이것은 불법입니다.
int & D; // must be set to a int variable.
그러나 벡터를 생성 할 때는 생성시 해당 항목에 값을 할당 할 방법이 없습니다. 당신은 본질적으로 마지막 예제를 전부 다 만들고 있습니다.
Ion Todirel은 이미을 사용하여 YES라고 대답했습니다 std::reference_wrapper
. C ++ 11 부터을 std::vector
사용하여 객체를 검색 하고 참조를 제거 하는 메커니즘이 std::remove_reference
있습니다. 아래는 사용하여 컴파일 예를 들어 주어진 g++
및 clang
옵션을 함께
-std=c++11
하고 성공적으로 실행합니다.
#include <iostream>
#include <vector>
#include<functional>
class MyClass {
public:
void func() {
std::cout << "I am func \n";
}
MyClass(int y) : x(y) {}
int getval()
{
return x;
}
private:
int x;
};
int main() {
std::vector<std::reference_wrapper<MyClass>> vec;
MyClass obj1(2);
MyClass obj2(3);
MyClass& obj_ref1 = std::ref(obj1);
MyClass& obj_ref2 = obj2;
vec.push_back(obj_ref1);
vec.push_back(obj_ref2);
for (auto obj3 : vec)
{
std::remove_reference<MyClass&>::type(obj3).func();
std::cout << std::remove_reference<MyClass&>::type(obj3).getval() << "\n";
}
}
boost::ptr_vector<int>
작동합니다.
편집 : 을 사용하는 것이 좋습니다 std::vector< boost::ref<int> >
. 이는 기본 구성을 할 수 없기 때문에 작동하지 않습니다 boost::ref
.
C ++ 언어의 결함입니다. 참조 주소를 가져 오면 참조 된 오브젝트의 주소가 생성되므로 참조에 대한 포인터를 얻을 수 없으므로 참조 주소를 사용할 수 없습니다. std::vector
요소에 대한 포인터와 함께 작동하므로 저장되는 값을 가리킬 수 있어야합니다. 대신 포인터를 사용해야합니다.
TL; DR
다음 std::reference_wrapper
과 같이 사용하십시오 .
#include <functional>
#include <string>
#include <vector>
#include <iostream>
int main()
{
std::string hello = "Hello, ";
std::string world = "everyone!";
typedef std::vector<std::reference_wrapper<std::string>> vec_t;
vec_t vec = {hello, world};
vec[1].get() = "world!";
std::cout << hello << world << std::endl;
return 0;
}
긴 대답
으로 표준 제안 , 표준 컨테이너 X
유형의 객체를 포함 T
, T
수 있어야 Erasable
에서 X
.
Erasable
다음식이 잘 구성되어 있음을 의미합니다.
allocator_traits<A>::destroy(m, p)
A
컨테이너의 할당 자 유형이고 m
할당 자 인스턴스이며 p
유형의 포인터입니다 *T
. 정의는 여기 를 참조 하십시오Erasable
.
기본적 std::allocator<T>
으로 벡터의 할당 자로 사용됩니다. 기본 할당 자에서 요구 사항은 유효성과 같습니다 p->~T()
(참고 T
는 참조 유형이며 참조에 대한 p
포인터 임). 그러나 참조에 대한 포인터는 불법 이므로 표현식이 제대로 구성되지 않았습니다.
다른 사람들이 언급했듯이, 대신 포인터 벡터를 사용하게 될 것입니다.
그러나 대신 ptr_vector 를 사용하는 것이 좋습니다!
다른 의견에서 알 수 있듯이 포인터 사용에 국한됩니다. 그러나 그것이 도움이된다면, 포인터와 직접 대면하지 않는 한 가지 기술이 있습니다.
다음과 같은 작업을 수행 할 수 있습니다.
vector<int*> iarray;
int default_item = 0; // for handling out-of-range exception
int& get_item_as_ref(unsigned int idx) {
// handling out-of-range exception
if(idx >= iarray.size())
return default_item;
return reinterpret_cast<int&>(*iarray[idx]);
}
참고 URL : https://stackoverflow.com/questions/922360/why-cant-i-make-a-vector-of-references
'Programing' 카테고리의 다른 글
Java에서 최종 키워드를 사용하면 성능이 향상됩니까? (0) | 2020.03.06 |
---|---|
충돌하는 Git rebase 도중에 "그들의"변화를 얻는 방법? (0) | 2020.03.06 |
Python에서 stdout을 파이핑 할 때 올바른 인코딩 설정 (0) | 2020.03.06 |
"만들기"에 대한 인수 전달 (0) | 2020.03.06 |
탭 대신 공백을 사용하도록 메모장 ++을 구성하려면 어떻게해야합니까? (0) | 2020.03.06 |