2009-04-03 2 views
0

std :: set of custom objects를 반환하는 (C++) 메서드를 작성하고 싶습니다. 그러나 개체를 삽입 할 때 사용되는 비교자를 노출하고 싶지 않으므로이를 개인 클래스로 만듭니다. (반환 할 때 암시 적으로)개인용 비교기를 사용하여 std :: set을 반환하는 방법

std::set<some_class, some_class_comparator> return_object; 

가 지금은 집합을 반환하려는, 그래서 같이 캐스팅해야합니다 : 나는 다음과 같은 설정을 만들

(const std::set<some_class>) return_object; 

이것은 컴파일러가 불평된다 . 비교기를 사용하여 변경 가능하지 않은 세트로 변환 할 수있는 방법이 있습니까?

덕분에 많이 나는 그렇게 생각하지 않습니다

홀거

+0

왜 비교기가없는 리턴 세트가 필요한지 설명하십시오. 그리고 당신은 돌아온 후에 어떤 것을 사용할 것입니다. – bayda

+0

또한 "개인 수업"은 무엇을 의미합니까? –

+0

저에게 개인 클래스는 잠재적 사용자가 결코 볼 수없는 클래스입니다. 이것은 그가 그것을 묘사하는 헤더를 결코 얻지 못할 것이라는 것을 의미합니다. –

답변

1

. AFAIK std::set<some_class>std::set<some_class, std::less<some_class> >의 줄임말이므로 원하는대로 설정을 변환 할 수 없습니다.

비교기를 사용하지 않고 현재 항목을 순서대로 유지하는 다른 데이터 구조 (예 : 벡터)로 항목을 전송하는 것이 좋습니다.

+0

불행히도 반환 유형의 의미 론적 의미를 잃어 버리게 될 것입니다 - 사용자가 컬렉션의 고유 항목을 기대할 수 있음을 알았 으면합니다. –

+0

@hp : 집합은 고유성 이상을 나타냅니다. 불변의 사람조차도 여전히 로그의 복잡성을 가지고 find()를 수행하기 위해 비교자를 필요로한다. 그래서 비교기는 형식의 본질적인 부분이며 "버려 질 수 없습니다". –

+0

@ 에릭 : 네 말이 맞아. STL에서 :-). 일반적으로 (a.k.a. 수학) 세트는 고유해야하며, 기간은 - 세트가 우선 순위를 가져야한다는 것이 이상하다는 것을 알게됩니다. 이는 성능상의 이유 일 뿐이며 가능한 경우 사용자로부터 숨겨야합니다. –

4

없이 불변의 에 비교하여 변경 가능한 설정 을 시전 할 수있는 방법이 있습니까?

없음

std::set<some_class, some_class_comparator> 

std::set<some_class> 

다른, 관련이없는 유형이 완전히 때문이다. 템플릿은 바로 템플릿입니다. 컴파일 전에 유형을 생성하는 방법을 지정하는 방법입니다. 두 번째 경우에는 비교자가 std :: set과 함께 제공 될 기본 비교 자입니다.

some_class_comparotor가 비공개 일 필요가있는 강력한 이유가 있습니까? 독립된 독립 체일 수 있습니까? 수업의 공용 인터페이스를 오염시키지 않으시겠습니까?

+0

맞습니다. 캐스트 연산자를 사용하여 직관적으로 공분산하는 타입으로 생성 (구현) 될 수 있습니다. –

+0

그들은 실제로 공변 적이 지 않습니다. – MSalters

0

표준, 두 가지 유형의 표준입니다. < 유형, 비교기> 및 표준 : < 유형, DefaultComparator>.

0

가상 함수처럼 들리는 템플릿처럼 들리지 않는 구현 세부 정보를 호출자에서 숨기려고합니다. 내 생각에, 너 스스로에게 물어볼 필요가있어.이게 정말로 중요한거야? 그렇다면 IOpaqueSet 인터페이스 뒤에 클래스를 숨 깁니다. 물론, 다른 STL 작업을 수행 할 수는 없습니다.

+0

IOpaqueSet이 반복자를 구현하는 한 모든 STL 작업이 반복자에서 작동 할 수 있습니다. Cf. std :: set 자체, 그것은 일반적으로 빨간색 - 검은 나무에 대한 불투명 한 래퍼입니다. RB 트리를 반복 할 수는 없지만 세트를 반복 할 수 있습니다. – MSalters

1

당신의 가장 좋은 방법은이 같은 것입니다 :

class MyClass 
{ 
    class some_class_comparator; 
public: 
    typedef std::set<int, some_class_comparator> ReturnSet; 
    ReturnSet myMethod(); 
    // ... 
private: 
    class some_class_comparator 
    { 
    public: 
     bool operator< (MyClass& m) {return true;} 
    }; 
}; 

//later... 
MyClass::ReturnSet s = my_class_instance.myMethod(); 
+0

이것을 할 수 있습니까? 소멸자가 공개되어야합니까? 나는 네가 할 수있는 것처럼, 네가 할 수 있다고 생각한다. 나는 그것이 작동 할 지 모르겠다. –

+0

그것은 작동합니다. 물론 MyClass :: ReturnSet :: key_compare를 사용하여이 문제를 해결할 수 있습니다. 그러나 프로그래머가 까다로워서 캡슐화를 원한다면 그는 일반적으로 할 수 있습니다. – rlbond

0

STL과는 내장 클래스를 많이 제공하지만, 또한 확장 가능한 프레임 워크입니다. :: it :: immutable_set을 정의하고 iterator를 정의하면 다른 STL 알고리즘이 iterator를 사용할 수 있습니다. immutable_set<T>은 가변적 인 std::set<T, comparator<T> > (다른 유형을 유도하기 때문에 다른 비교기를 지원하는 데 필요한 일부 템플릿 마술) 주위의 얇은 const 래퍼로 정의됩니다. immutable_set<T>::iterator::operator++std::set<T>::iterator::operator++ 등으로 전달됩니다.

관련 문제