이 스레드에서 설명한 것과 비슷한 상황이 있습니다 : Getting around Boost Multi-Index container's constant elemets.부스트 멀티 인덱스 항목의 비 인덱스 필드를 수정하는 가장 좋은 방법은 다음과 같습니다. vs mutable 수정
struct Data {
Controller controller;
const int indexed_data;
}
내 인덱스 데이터가 변경되지 않습니다,하지만 컨트롤러가 수행합니다 즉, 나는 boost multi index container이 같은 구조체를 들고있다. 그래서, 내 첫 번째 방법은 내가 modify 호출에 필요한 모든 수행했다 :
container.modify(it, [](auto& data) {
data.controller.nonConstFunction();
});
은 분명히이 나를 위해 일을하지만, 예외가 람다 내부에서 발생합니다 때이 방법의 행동을 이해하기 위해 몇 가지 테스트를 수행했다 (이 내 경우에 일어날 것), 나는 결과에 놀랐습니다 : 당신은 컨테이너의 내용을 인쇄하는 경우이 후
struct employee {
int id;
std::string name;
}
typedef multi_index_container<
employee,
indexed_by<
ordered_unique<BOOST_MULTI_INDEX_MEMBER(employee,int,id)>>
>
> employee_set;
employee_set es;
es.insert(employee{0,"Joe"});
es.insert(employee{1,"Carl"});
es.insert(employee{2,"Robert"});
es.insert(employee{4,"John"});
try {
auto it = es.find(4); // John
es.modify(it, [](auto& employee) {
employee.id = 1; // Same ID of Carl, should be erased
throw std::runtime_error("test");
});
} catch (const std::runtime_error& err) {
// handle error...
}
, 당신은 얻을 :
0 Joe
1 Carl
2 Robert
1 John
예외를 던지지 않고 직원의 ID를 이미 존재하는 ID로 변경하는 것만으로 인덱스에 대한 히트가 감지되고 수정중인 직원이 지워집니다.
내가 말했듯이, 나는 컨테이너의 키를 변경하지 않지만 이에 대해 알아 낸 후에 걱정된다. 이게 라이브러리 버그 야? 인덱스의 유효하지 않은 상태로 이어질 수있는 다른 상황이 있습니까? 또한 "유효하지 않은"항목 중 하나를 수동으로 삭제/수정하는 것 이외에 유효한 상태로 인덱스를 "다시 처리"하는 방법을 찾을 수 없었습니다. 그 (다시 내 자신의 경우에가는)에서 별도로
실제로 내 컨트롤러에 메소드를 호출 할 modify 가장 좋은 방법을 사용하고, 또는 나는 thread beforementioned의 조언을 따라 내 컨트롤러mutable
를 선언해야합니까? 후자는 나를 위해 매우 위험한 것처럼 보입니다. 아무래도
mutable
을 선언하여 색인을 쉽게 망칠 수 있기 때문에, 방금 전에 말했듯이 안전한 방법은 방금 너무 안전하지 않은 것으로 판명되었습니다.
감사합니다. 나는 당신이 강조한 발췌문을 이해하는 데 약간의 어려움을 겪었 음을 고백합니다. 실제로 그것은 내 문제와 관련이 깊었습니다. 어쨌든,'mod'를 실행할 때 어떤 키도 수정하지 않는다고 가정 할 때, 제가 언급 한 다른 스레드에서 스스로 제안한 것처럼'modify'를 사용하거나'mutable' 컨트롤러를 선언하겠습니까? –
글쎄요, 안전과 성능 사이에는 트레이드 오프가 있습니다. '수정'은 일관성을 검사하는 (즉, 키가 수정되지 않았 음을 확인하는) 고비용의 작업이며, '변경 가능'하는 것은 오버 헤드가 없습니다. 프로파일 링이 더 많은 성능이 필요하다는 것을 나타낼 때까지'modify'를 할 것입니다. –