C ++에서 튜플을 사용하는 것이 더 일반적이지 않은 이유는 무엇입니까? TR1 용

왜 아무도 C ++, Boost Tuple Library 나 TR1 용 표준 라이브러리 에서 튜플을 사용하지 않는 것 같습니까? 나는 많은 C ++ 코드를 읽었고 튜플의 사용을 거의 보지 못했지만 튜플이 많은 문제를 해결할 수있는 곳을 자주 볼 수 있습니다 (보통 함수에서 여러 값을 반환).

튜플을 사용하면 다음과 같은 모든 종류의 멋진 작업을 수행 할 수 있습니다.

tie(a,b) = make_tuple(b,a); //swap a and b

이것은 확실히 이것보다 낫습니다.

temp=a;
a=b;
b=temp;

물론 항상 이렇게 할 수 있습니다.

swap(a,b);

하지만 세 개의 값을 회전하려면 어떻게해야합니까? 튜플을 사용하여이를 수행 할 수 있습니다.

tie(a,b,c) = make_tuple(b,c,a);

튜플을 사용하면 함수에서 여러 변수를 반환하는 것이 훨씬 쉬워지며, 이는 값을 바꾸는 것보다 훨씬 더 일반적인 경우입니다. 참조를 사용하여 값을 반환하는 것은 확실히 우아하지 않습니다.

내가 생각하지 않는 튜플에 큰 단점이 있습니까? 그렇지 않다면 왜 거의 사용되지 않습니까? 느린가요? 아니면 단지 사람들이 그들에게 익숙하지 않은 것일까 요? 튜플을 사용하는 것이 좋은 생각입니까?



답변

아직 표준이 아니기 때문입니다. 비표준은 훨씬 더 큰 장애물이 있습니다. 프로그래머가 요구했기 때문에 Boost의 조각이 인기를 얻었습니다. (hash_map이 떠 오릅니다). 그러나 튜플은 편리하지만 사람들이 그것을 괴롭히는 것은 압도적이고 명확한 승리는 아닙니다.


답변

냉소적 인 대답은 많은 사람들이 C ++로 프로그래밍하지만 더 높은 수준의 기능을 이해하거나 사용하지 않는다는 것입니다. 때로는 허용되지 않기 때문이지만 많은 사람들은 단순히 시도하거나 이해하지 않습니다.

부스트가 아닌 예 : 얼마나 많은 사람들이에있는 기능을 사용 <algorithm>합니까?

즉, 많은 C ++ 프로그래머는 단순히 C ++ 컴파일러를 사용하는 C 프로그래머이며 아마도 std::vectorstd::list. 그것이 사용이 boost::tuple더 일반적이지 않은 이유 중 하나 입니다.


답변

C ++ 튜플 구문은 대부분의 사람들이 원하는 것보다 훨씬 더 장황 할 수 있습니다.

치다:

typedef boost::tuple<MyClass1,MyClass2,MyClass3> MyTuple;

따라서 튜플을 광범위하게 사용하려면 모든 곳에서 튜플 typedef를 얻거나 모든 곳에서 성가신 긴 유형 이름을 얻습니다. 나는 튜플을 좋아합니다. 필요한 경우 사용합니다. 그러나 일반적으로 N 요소 인덱스 또는 멀티 맵을 사용하여 범위 반복기 쌍을 연결할 때와 같은 몇 가지 상황으로 제한됩니다. 그리고 그것은 일반적으로 매우 제한된 범위에 있습니다.

Haskell이나 Python과 비교할 때 모두 매우 추하고 엉망진창입니다. C ++ 0x가 여기에 도착하면 ‘auto’키워드 튜플이 훨씬 더 매력적으로 보이기 시작할 것입니다.

튜플의 유용성은 선언, 압축 및 압축 해제에 필요한 키 입력 수에 반비례합니다.


답변

저에게는 습관입니다. 튜플은 저에게 새로운 문제를 해결하지 못합니다. 단지 몇 가지만 이미 잘 처리 할 수 ​​있습니다. 가치를 바꾸는 것은 여전히 ​​구식 방식보다 더 쉽다고 느낍니다. 그리고 더 중요한 것은 “더 나은”교환 방법에 대해 생각하지 않는다는 것입니다. 있는 그대로 충분합니다.

개인적으로 튜플이 여러 값을 반환하는 훌륭한 솔루션이라고 생각하지 않습니다 struct.


답변

하지만 세 개의 값을 회전하려면 어떻게해야합니까?

swap(a,b);
swap(b,c);  // I knew those permutation theory lectures would come in handy.

좋아요, 그래서 4 개의 etc 값으로, 결국 n- 튜플은 n-1 스왑보다 적은 코드가됩니다. 그리고 기본 스왑을 사용하면 컴파일러가 간단한 유형에 대해 해결할 수 있기를 바라지 만 3주기 템플릿을 직접 구현 한 경우 가질 수있는 4 대신 6 개의 할당을 수행합니다.

다음과 같이 스왑이 다루기 어렵거나 부적절한 시나리오를 생각 해낼 수 있습니다.

tie(a,b,c) = make_tuple(b*c,a*c,a*b);

포장을 풀기가 조금 어색합니다.

그러나 요점은 튜플이 좋은 가장 일반적인 상황을 처리하는 알려진 방법이 있으므로 튜플을 차지하는 데 큰 긴급 성이 없다는 것입니다. 다른 것이 없다면 다음과 같은 확신이 없습니다.

tie(a,b,c) = make_tuple(b,c,a);

6 개의 복사본을 만들지 않기 때문에 일부 유형에는 전혀 적합하지 않습니다 (컬렉션이 가장 분명함). 튜플이 “대형”유형에 대한 좋은 생각이라고 저를 설득하십시오.

여러 값을 반환하는 경우 값이 호환되지 않는 유형이면 튜플이 완벽하지만 호출자가 잘못된 순서로 가져올 수있는 경우 튜플을 좋아하지 않는 사람도 있습니다. 일부 사람들은 여러 반환 값을 전혀 좋아하지 않으며 더 쉽게 사용하여 사용을 장려하고 싶지 않습니다. 어떤 사람들은 인 / 아웃 매개 변수에 대해 명명 된 구조를 선호하며 야구 방망이로 튜플을 사용하도록 설득 할 수 없을 것입니다. 맛에 대한 설명이 없습니다.


답변

많은 사람들이 지적했듯이 튜플은 다른 기능만큼 유용하지 않습니다.

  1. 스와핑 및 회전 기믹은 단순한 기믹입니다. 그들은 전에 그들을 본 적이없는 사람들에게 완전히 혼란스럽고, 거의 모든 사람들이기 때문에 이러한 속임수는 단지 열악한 소프트웨어 엔지니어링 관행 일뿐입니다.

  2. 튜플을 사용하여 여러 값을 반환하는 것은 명명 된 유형을 반환하거나 명명 된 참조를 사용하는 대안보다 훨씬 덜 자체 문서화됩니다. 이 자체 문서화가 없으면 반환 값이 상호 변환 가능하고 더 현명하지 않은 경우 반환 된 값의 순서를 혼동하기 쉽습니다.


답변

모든 사람이 boost를 사용할 수있는 것은 아니며 TR1은 아직 널리 사용되지 않습니다.