C ++에서 튜플을 사용하는 것이 더 일반적이지 않은 이유는 무엇입니까?
부스트 튜플 라이브러리 또는 TR1의 표준 라이브러리 인 C ++에서 튜플을 사용하는 사람이없는 이유는 무엇 입니까? 나는 많은 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);
튜플은 또한 함수에서 여러 변수를 반환하기가 훨씬 쉬워 지므로 값을 바꾸는 것보다 훨씬 일반적인 경우 일 수 있습니다. 참조를 사용하여 값을 반환하는 것은 그리 우아하지 않습니다.
내가 생각하지 않는 튜플에 큰 단점이 있습니까? 그렇지 않다면 왜 거의 사용되지 않습니까? 그들은 느리다? 아니면 사람들이 그들에게 익숙하지 않다는 것입니까? 튜플을 사용하는 것이 좋습니다?
아직 표준이 아니기 때문입니다. 비표준의 것은 장애물이 훨씬 높습니다. 프로그래머가 그들을 요구하고 있기 때문에 부스트 조각 인기가되었습니다. (hash_map이 떠 오릅니다). 그러나 튜플은 편리하지만 사람들이 그것을 귀찮게하는 것은 그렇게 압도적이고 명확한 승리는 아닙니다.
냉소적 인 대답은 많은 사람들이 C ++로 프로그래밍하지만 더 높은 수준의 기능을 이해하거나 사용하지 않는다는 것입니다. 때로는 허용되지 않기 때문에 많은 사람들이 시도하지 않거나 이해하지도 않습니다.
부스트가 아닌 예 : <algorithm>
?에있는 기능을 사용하는 사람은 몇 명 입니까?
다시 말해서, 많은 C ++ 프로그래머는 C ++ 컴파일러를 사용하는 아마도 C 프로그래머이며 아마도 std::vector
and std::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.
OK, so with 4 etc values, eventually the n-tuple becomes less code than n-1 swaps. And with default swap this does 6 assignments instead of the 4 you'd have if you implemented a three-cycle template yourself, although I'd hope the compiler would solve that for simple types.
You can come up with scenarios where swaps are unwieldy or inappropriate, for example:
tie(a,b,c) = make_tuple(b*c,a*c,a*b);
is a bit awkward to unpack.
Point is, though, there are known ways of dealing with the most common situations that tuples are good for, and hence no great urgency to take up tuples. If nothing else, I'm not confident that:
tie(a,b,c) = make_tuple(b,c,a);
doesn't do 6 copies, making it utterly unsuitable for some types (collections being the most obvious). Feel free to persuade me that tuples are a good idea for "large" types, by saying this ain't so :-)
For returning multiple values, tuples are perfect if the values are of incompatible types, but some folks don't like them if it's possible for the caller to get them in the wrong order. Some folks don't like multiple return values at all, and don't want to encourage their use by making them easier. Some folks just prefer named structures for in and out parameters, and probably couldn't be persuaded with a baseball bat to use tuples. No accounting for taste.
As many people pointed out, tuples are just not that useful as other features.
The swapping and rotating gimmicks are just gimmicks. They are utterly confusing to those who have not seen them before, and since it is pretty much everyone, these gimmicks are just poor software engineering practice.
Returning multiple values using tuples is much less self-documenting then the alternatives -- returning named types or using named references. Without this self-documenting, it is easy to confuse the order of the returned values, if they are mutually convertible, and not be any wiser.
Not everyone can use boost, and TR1 isn't widely available yet.
When using C++ on embedded systems, pulling in Boost libraries gets complex. They couple to each other, so library size grows. You return data structures or use parameter passing instead of tuples. When returning tuples in Python the data structure is in the order and type of the returned values its just not explicit.
You rarely see them because well-designed code usually doesn't need them- there are not to many cases in the wild where using an anonymous struct is superior to using a named one. Since all a tuple really represents is an anonymous struct, most coders in most situations just go with the real thing.
Say we have a function "f" where a tuple return might make sense. As a general rule, such functions are usually complicated enough that they can fail.
If "f" CAN fail, you need a status return- after all, you don't want callers to have to inspect every parameter to detect failure. "f" probably fits into the pattern:
struct ReturnInts ( int y,z; }
bool f(int x, ReturnInts& vals);
int x = 0;
ReturnInts vals;
if(!f(x, vals)) {
..report error..
..error handling/return...
}
That isn't pretty, but look at how ugly the alternative is. Note that I still need a status value, but the code is no more readable and not shorter. It is probably slower too, since I incur the cost of 1 copy with the tuple.
std::tuple<int, int, bool> f(int x);
int x = 0;
std::tuple<int, int, bool> result = f(x); // or "auto result = f(x)"
if(!result.get<2>()) {
... report error, error handling ...
}
Another, significant downside is hidden in here- with "ReturnInts" I can add alter "f"'s return by modifying "ReturnInts" WITHOUT ALTERING "f"'s INTERFACE. The tuple solution does not offer that critical feature, which makes it the inferior answer for any library code.
Certainly tuples can be useful, but as mentioned there's a bit of overhead and a hurdle or two you have to jump through before you can even really use them.
If your program consistently finds places where you need to return multiple values or swap several values, it might be worth it to go the tuple route, but otherwise sometimes it's just easier to do things the classic way.
Generally speaking, not everyone already has Boost installed, and I certainly wouldn't go through the hassle of downloading it and configuring my include directories to work with it just for its tuple facilities. I think you'll find that people already using Boost are more likely to find tuple uses in their programs than non-Boost users, and migrants from other languages (Python comes to mind) are more likely to simply be upset about the lack of tuples in C++ than to explore methods of adding tuple support.
As a data-store std::tuple
has the worst characteristics of both a struct
and an array; all access is nth position based but one cannot iterate through a tuple
using a for
loop.
So if the elements in the tuple
are conceptually an array, I will use an array and if the elements are not conceptually an array, a struct (which has named elements) is more maintainable. ( a.lastname
is more explanatory than std::get<1>(a)
).
This leaves the transformation mentioned by the OP as the only viable usecase for tuples.
I have a feeling that many use Boost.Any and Boost.Variant (with some engineering) instead of Boost.Tuple.
참고URL : https://stackoverflow.com/questions/855110/why-is-the-use-of-tuples-in-c-not-more-common
'Programing' 카테고리의 다른 글
Xcode에서 서명 신원 문제를 해결할 수 없습니다 (0) | 2020.07.14 |
---|---|
요소의 n 번째 인스턴스를 가져 오기위한 XPath 쿼리 (0) | 2020.07.14 |
CVS에서 Git으로 이동 : $ Id : $ 상당? (0) | 2020.07.14 |
배열에서 첫 번째 요소를 제외한 모든 요소 가져 오기 (0) | 2020.07.14 |
rspec 요청 사양에서 요청 헤더를 설정하는 방법은 무엇입니까? (0) | 2020.07.14 |