문제

대부분의 프로그래머로서 나는 문맹 프로그래밍의 원리를 존경하고 따르려고 노력하지만 C ++에서는 일상적으로 나 자신을 사용합니다. std::pair, 일반적인 공통 작업. 하지만 std::pair IMHO, 문맹 프로그래밍의 사악한 적 ...

요점은 하루나 이틀 전에 쓴 코드로 돌아 왔을 때입니다. std::pair (일반적으로 반복자로서) 나는 나 자신에게 궁금하다 "iter-> 먼저 iter-> 두 번째는 무엇을 의미 했습니까 ???".

나는 다른 사람들이 그들의 것을 볼 때 같은 의심을 가지고 있다고 생각합니다. std::pair 코드는 궁금합니다. 누구든지 사용할 때 문해력을 복구 할 수있는 좋은 해결책을 제시해야합니다. std::pair?

도움이 되었습니까?

해결책

이건 어때:

struct MyPair : public std::pair < int, std::string >
{
    const int& keyInt() { return first; }
    void keyInt( const int& keyInt ) { first = keyInt; }
    const std::string& valueString() { return second; }
    void valueString( const std::string& valueString ) { second = valueString; }
};

약간의 장점이지만 코드에 이것을 사용하면 책을 읽기가 좀 더 쉽게 만들 수 있습니다.

std::vector < MyPair > listPairs;

std::vector < MyPair >::iterator iterPair( listPairs.begin() );
if ( iterPair->keyInt() == 123 )
    iterPair->valueString( "hello" );

이 외에는 물건을 훨씬 더 명확하게 만들 수있는은 총알을 볼 수 없습니다.

다른 팁

std::pair 본질적으로 익명 열이있는 "로컬"및 본질적으로 익명 유형을 만드는 좋은 방법입니다. 유형과 열의 이름을 지정 해야하는 넓은 어휘 공간 위에 특정 쌍을 사용하는 경우 평원을 사용합니다. struct 대신에.

typedef std::pair<bool, int> IsPresent_Value;
typedef std::pair<double, int> Price_Quantity;

... 당신은 요점을 얻습니다.

당신은 단지 첫 번째와 두 번째에 대한 참조를 반환하지만 훨씬 더 읽기 쉬운 두 쌍의 getters (const 및 non)를 만들 수 있습니다. 예를 들어:

string& GetField(pair& p) { return p.first; }
int& GetValue(pair& p) { return p.second; }

어떤 회원이 무엇을 보유하고 있는지 기억하지 않고 주어진 쌍에서 필드와 가치 멤버를 얻을 수 있습니다.

이것을 많이 사용 할 것으로 예상되면, 이름과 유형을 고려할 때 Make_pair_getters (필드, 문자열, 값, int) 등을 고려할 때 그 getters를 생성하는 매크로를 만들 수도 있습니다. Getters를 간단하게 만들면 컴파일러가 클릭을 최적화 할 수 있으므로 런타임에 오버 헤드를 추가하지 않습니다. 그리고 매크로를 사용하면 쌍을 사용하는 모든 용도로 그 게터를 만들 수 있습니다.

부스트 튜플을 사용할 수는 있지만 실제로는 근본적인 문제를 변경하지 않습니다. 진짜 작은 적분 유형으로 쌍/튜플의 각 부분에 액세스하거나 더 많은 '문맹'코드를 원하십니까? 보다 이 질문 나는 잠시 뒤로 올렸다.

하지만, 부스트 :: 선택 사항 내가 찾은 유용한 도구는 쌍/튜플이 대답으로 선전되는 몇 가지 경우를 대체합니다.

최근에 나는 나 자신을 사용하는 것을 발견했다 boost::tuple 대체품으로 std::pair. 각 멤버의 열거자를 정의 할 수 있으므로 각 구성원이 무엇인지 분명합니다.

typedef boost::tuple<int, int> KeyValueTuple;
enum {
  KEY
  , VALUE
};

void foo (KeyValueTuple & p) {
    p.get<KEY> () = 0;
    p.get<VALUE> () = 0;
}

void bar (int key, int value)
{
  foo (boost:tie (key, value));
}

BTW,이 접근법을 사용하는 데 숨겨진 비용이있는 경우 의견을 환영합니다.

편집 : 글로벌 범위에서 이름을 제거하십시오.

글로벌 네임 스페이스에 대한 빠른 의견. 일반적으로 나는 사용합니다.

struct KeyValueTraits
{
  typedef boost::tuple<int, int> Type;
  enum {
    KEY
    , VALUE
  };
};

void foo (KeyValueTuple::Type & p) {
    p.get<KeyValueTuple::KEY> () = 0;
    p.get<KeyValueTuple::VALUE> () = 0;
}

그것은 그 사건으로 보인다 boost::fusion 정체성과 가치를 더 가깝게 묶습니다.

Alex가 언급했듯이 std::pair 매우 편리하지만 혼란 스러울 때 구조를 만들고 같은 방식으로 사용하십시오. std::pair 코드, 그렇게 복잡하지 않습니다.

나는 std :: 쌍을 좋아하지 않으며 std :: map에 사용된다. 맵 항목에는 멤버 키와 가치가 있어야한다.
나는 이것을 피하기 위해 Boost :: MIC를 사용했습니다. 그러나 Boost :: MIC도 비용이 제공됩니다.

또한 STD :: 쌍을 반환하면 읽을 수없는 코드가 적습니다.

if (cntnr.insert(newEntry).second) { ... }

???

또한 STD :: 쌍은 일반적으로 2 값이 필요한 게으른 프로그래머에 의해 일반적으로 사용되지만 이러한 값이 함께 필요한 경우 왜 그런지 생각하지 않았다는 것을 알았습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top