เหตุใดการใช้ tuples ใน C ++ จึงไม่ธรรมดา


125

เหตุใดจึงดูเหมือนไม่มีใครใช้ tuples ใน C ++ ทั้งBoost Tuple Libraryหรือไลบรารีมาตรฐานสำหรับ TR1 ฉันอ่านโค้ด C ++ มาเยอะแล้วและไม่ค่อยเห็นการใช้ทูเปิล แต่ฉันมักจะเห็นสถานที่มากมายที่ทูเปิลสามารถแก้ปัญหาต่างๆได้ (โดยปกติจะคืนค่าหลายค่าจากฟังก์ชัน)

Tuples ช่วยให้คุณทำสิ่งดีๆได้ทุกประเภทเช่นนี้:

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);

Tuples ยังช่วยให้สามารถส่งคืนตัวแปรหลายตัวจากฟังก์ชันได้ง่ายกว่ามากซึ่งอาจเป็นกรณีที่พบได้บ่อยกว่าการแลกเปลี่ยนค่า การใช้การอ้างอิงเพื่อส่งกลับค่าเป็นสิ่งที่ไม่สวยงามอย่างแน่นอน

มีข้อบกพร่องใหญ่ ๆ สำหรับสิ่งที่ฉันไม่ได้นึกถึงหรือไม่? ถ้าไม่เป็นเช่นนั้นทำไมพวกเขาจึงไม่ค่อยใช้? ช้ากว่าไหม หรือว่าแค่คนไม่ชิน? เป็นความคิดที่ดีที่จะใช้ tuples หรือไม่?


18
+1 สำหรับเคล็ดลับการแลกเปลี่ยนทูเพิลที่ชาญฉลาด :)
kizzx2

10
a = a ^ b; b = a ^ b; a = a ^ b;
Gerardo Marset

3
สิ่งที่เพิ่มขึ้นของ IMO นั้นสะดวกในภาษาพิมพ์ที่ไม่ชัดเจนหรือภาษาที่เป็นโครงสร้างดั้งเดิม ตัวอย่างเช่นใน Python หรือ PHP พวกเขาทำให้ชีวิตง่ายขึ้นในขณะที่ใน C ++ มีการพิมพ์มากเกินไป (เพื่อสร้างจากเทมเพลต) และประโยชน์น้อยเกินไป
doc

4
ความคิดเห็นต่อ OP: ฉันคิดว่าคำตอบที่ยอมรับในปัจจุบันนั้นล้าสมัยไปแล้วจนถึงจุดที่ผิดจริง คุณอาจต้องการพิจารณาตัวเลือกของคำตอบที่ยอมรับอีกครั้ง
ulidtko

8
@GerardoMarset เอาจริงดิ?
thesaint

คำตอบ:


43

เพราะยังไม่ได้มาตรฐาน. สิ่งใดที่ไม่ได้มาตรฐานย่อมมีอุปสรรค์ที่สูงกว่ามาก ชิ้นส่วนของ Boost ได้รับความนิยมเนื่องจากโปรแกรมเมอร์ต่างเรียกร้องให้พวกเขา (hash_map กระโดดถึงใจ) แต่แม้ว่าทูเพิลจะมีประโยชน์ แต่ก็ไม่ได้เป็นการชนะที่ท่วมท้นและชัดเจนขนาดนั้นที่ผู้คนจะรำคาญ


1
ผู้คนดูเหมือนจะใช้ส่วนอื่น ๆ ของ Boost อย่างบ้าคลั่ง แม้ว่าแผนที่แฮชจะมีประโยชน์มากกว่าโดยทั่วไปอย่างมาก
Zifre

ฉันไม่รู้รายละเอียดของสิ่งที่คุณเห็น แต่ฉันเดาว่าชิ้นส่วนที่ผู้คนใช้กันอย่างบ้าคลั่งเป็นคุณสมบัติที่พวกเขาต้องการจริงๆ ดังนั้น (เดาอีกครั้ง) ความนิยมของแผนที่แฮชตัวชี้ที่นับและอื่น ๆ ทูเพิลมีประโยชน์ แต่ไม่ใช่สิ่งที่กระโดดออกมาเพื่อเติมเต็มหลุม ผลตอบแทนไม่ชัดเจน คุณต้องหมุนวัตถุ N บ่อยแค่ไหน? (ตรงข้ามกับการต้องหมุนเวกเตอร์ยาวตามอำเภอใจ) และผู้คนจะใช้ในการส่งคืนค่าในโดยการอ้างอิงหรือส่งคืนคลาสหรือโครงสร้างขนาดเล็ก
Alan De Smet

20
ตอนนี้เป็นส่วนหนึ่งของมาตรฐาน C ++ 11 แล้ว: en.cppreference.com/w/cpp/utility/tuple
Roman Susi

124

คำตอบที่เหยียดหยามคือหลาย ๆ คนเขียนโปรแกรมใน C ++ แต่ไม่เข้าใจและ / หรือใช้ฟังก์ชันระดับสูงกว่า บางครั้งอาจเป็นเพราะไม่ได้รับอนุญาต แต่หลายคนไม่พยายาม (หรือแม้แต่เข้าใจ)

เป็นตัวอย่างที่ไม่เพิ่ม: มีกี่คนที่ใช้ฟังก์ชันที่พบใน<algorithm>?

ในคำอื่น ๆ อีกมากมาย c ++ เขียนโปรแกรมเป็นเพียงโปรแกรมเมอร์ C โดยใช้ C ++ คอมไพเลอร์และอาจและstd::vector std::listนั่นเป็นเหตุผลหนึ่งที่ทำให้การใช้งานboost::tupleไม่ธรรมดามากขึ้น


18
-1 จากฉันเพราะโปรแกรมเมอร์ C ++ ไม่โง่เท่าคำตอบนี้ทำให้พวกเขาฟังดูดี
user541686

5
@Mehrdad จากการตรวจสอบโค้ด C ++ จำนวนมากทั้งเชิงพาณิชย์และไม่อ่านเนื้อหา C ++ จำนวนมากฉันคิดว่ามันค่อนข้างปลอดภัยที่จะบอกว่านักพัฒนา "C ++" ส่วนใหญ่เป็นเพียงนักพัฒนา C ที่ไม่สามารถรับสิ่งที่บริสุทธิ์ได้ C คอมไพเลอร์ ตัวอย่างเช่นเทมเพลตแทบจะขาดหายไปจากวัสดุส่วนใหญ่ (สิ่งที่ฉันเรียนรู้ที่จะรักมาก) การแฮ็กมาโครแปลก ๆ เป็นเรื่องปกติและเนมสเปซถูกใช้งานน้อยมาก
ชัดเจนขึ้น

5
คำตอบไร้สาระ หากใครต้องการพวกเขาก็จะตามทัน ไม่จำเป็น ดังนั้นจึงไม่ได้ใช้ การบอกว่าไม่ใช้เพราะเข้าใจได้ไม่ยากถือว่าแย่
Michael Chourdakis

9
@ ไมเคิลไร้สาระความคิดเห็น ไม่จำเป็นต้องมีอะไรในการเขียนโปรแกรมเมื่อคุณมีชุดย่อยของภาษาทัวริงที่สมบูรณ์ การขาดการใช้งานไม่ได้หมายความว่าทุกคนเข้าใจโครงสร้าง C ++ ระดับสูงกว่าและเลือกที่จะไม่ใช้
Trey Jackson

4
Tbh ฉันไม่เคยมีความต้องการ std :: tuple นอก metaprogramming เทมเพลตตัวแปร ไม่มีจุดใดในชีวิตที่ฉันนั่งลงด้วยใบหน้าเศร้า ๆ คิดว่า "ถ้ามีเพียงสิ่งเหล่านั้น" ในความเป็นจริงเมื่อฉันมองไปที่สิ่งทอฉันคิดว่า "คนบ้าอะไรจะต้องการมัน (ฉันจะไม่คิดว่าตัวเองมีสติ)" ผู้คนที่อยู่นอกการเขียนโปรแกรมเมตาดูเหมือนจะใช้สิ่งเหล่านี้เป็น "Anonymous Struct" ซึ่งน่าเกลียดมากและบ่งบอกถึงการขาดคุณภาพของโค้ดและการบำรุงรักษาอย่างมากในหัวของพวกเขา
thesaint

23

ไวยากรณ์ทูเปิลของ C ++ สามารถใช้งานได้มากกว่าที่คนส่วนใหญ่ต้องการ

พิจารณา:

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

ดังนั้นหากคุณต้องการใช้ tuples อย่างกว้างขวางคุณจะได้รับ tuple typedef ทุกที่หรือคุณจะได้รับชื่อประเภทที่ยาวจนน่ารำคาญทุกที่ ฉันชอบ tuples ฉันใช้เมื่อจำเป็น แต่โดยปกติจะ จำกัด ไว้เพียงไม่กี่สถานการณ์เช่นดัชนีองค์ประกอบ N หรือเมื่อใช้มัลติแมปเพื่อผูกคู่ตัวทำซ้ำช่วง และมักจะอยู่ในขอบเขตที่ จำกัด มาก

ทุกอย่างดูน่าเกลียดและแฮ็คเมื่อเทียบกับบางอย่างเช่น Haskell หรือ Python เมื่อ C ++ 0x มาถึงที่นี่และเราได้รับ tuples คีย์เวิร์ด 'auto' จะเริ่มดูน่าสนใจมากขึ้น

ประโยชน์ของทูเปิลนั้นแปรผกผันกับจำนวนการกดแป้นพิมพ์ที่จำเป็นในการประกาศแพ็คและแกะออกจากกล่อง


คนส่วนใหญ่จะ "ใช้การเพิ่มเนมสเปซ" และไม่ต้องพิมพ์ boost ::. ฉันไม่คิดว่าการพิมพ์ทูเพิลเป็นปัญหามากขนาดนั้น ที่กล่าวว่าฉันคิดว่าคุณมีประเด็น รถยนต์อาจทำให้ผู้คนจำนวนมากเริ่มใช้ทูเปิล
Zifre

2
@Zifre: ปัญหาคือคุณไม่ควรทำ "ใช้เนมสเปซ X" ภายในไฟล์ส่วนหัวเพราะมันบังคับให้เนมสเปซมลพิษและทำลายเนมสเปซ
Mr Fooz

1
อ่าใช่ฉันลืมเกี่ยวกับส่วนหัว แต่ภายในรหัสโปรแกรมคุณไม่จำเป็นต้องกังวลเกี่ยวกับเรื่องนี้ และเมื่อเรามี C ++ 0x แล้วเราสามารถใช้ auto ซึ่งจะช่วยลดการพิมพ์ได้มาก
Zifre

19
มันเป็นแค่ฉัน? ผมไม่คิดว่าการประหยัดการพิมพ์ 7 ตัวอักษรของ "เพิ่ม ::" คือสิ่งที่เขากำลังพูดถึง แต่ค่อนข้างอื่น ๆ 33 ตัวอักษร นั่นเป็นการพิมพ์ชื่อคลาสจำนวนมากโดยเฉพาะอย่างยิ่งหากมีการกำหนดขอบเขตเนมสเปซด้วย ใช้ boost :: tuple <std :: string, std :: set <std :: string>, std :: vector <My :: Scoped :: LongishTypeName>> เป็นตัวอย่างที่ไร้สาระ
Ogre Psalm33

10

สำหรับฉันมันเป็นนิสัยลงมือทำ: ทูเปิลไม่ได้แก้ปัญหาใหม่ ๆ ให้ฉันมีเพียงไม่กี่อย่างที่ฉันสามารถจัดการได้ดีอยู่แล้ว การแลกเปลี่ยนค่ายังคงให้ความรู้สึกง่ายกว่าแบบเดิม - และที่สำคัญฉันไม่ได้คิดว่าจะเปลี่ยน "ดีกว่า" ได้อย่างไร มันดีพออย่างที่เป็นอยู่

โดยส่วนตัวแล้วฉันไม่คิดว่า tuples เป็นทางออกที่ดีในการคืนค่าหลายค่า - ดูเหมือนจะเป็นงานสำหรับstructs


4
'ฉันไม่ได้คิดเกี่ยวกับวิธีการสลับ "ที่ดีขึ้น" - เมื่อฉันเขียนโค้ดฉันเขียนบั๊ก การลดความซับซ้อนของโค้ดจะช่วยลดจำนวนข้อบกพร่องที่ฉันเขียน ฉันเกลียดการสร้างจุดบกพร่องเดิม ๆ ซ้ำแล้วซ้ำเล่า ใช่ฉันคิดว่าจะ <strike> สลับ </> โค้ดให้ดีขึ้นได้อย่างไร ชิ้นส่วนที่เคลื่อนไหวน้อยลง (LOC, ตัวแปรอุณหภูมิ, ตัวระบุประเภทผิด), โค้ดที่อ่านได้มากขึ้น รหัสที่ดี
sehe

ตกลง. คลาสที่อยู่ในตัวชี้อัตโนมัติหรือตัวชี้อัจฉริยะคือ type-save ฉันเคยใช้ทูเปิลครั้งหนึ่ง แต่เขียนโค้ดใหม่โดยใช้คลาส retValue.state ชัดเจนกว่า retValue.get <0> ()
Valentin Heinitz

1
@sehe: การเขียนโค้ดที่ดีขึ้นและอ่านได้มากขึ้นก็เป็นเป้าหมายของฉันเช่นกัน การเพิ่มประเภทของไวยากรณ์มากขึ้นมีค่าใช้จ่ายและฉันไม่เชื่อว่า "การแลกเปลี่ยนที่ดีขึ้น" จะช่วยให้คุณคิดเกี่ยวกับไวยากรณ์ประเภทต่างๆมากขึ้นสำหรับโค้ดทุกบรรทัดที่คุณอ่าน
ojrac

8

แต่ถ้าคุณต้องการหมุนสามค่าล่ะ?

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

ตกลงดังนั้นด้วยค่าอื่น ๆ 4 ค่าในที่สุด n-tuple จะกลายเป็นรหัสน้อยกว่าการแลกเปลี่ยน n-1 และด้วยการสลับค่าเริ่มต้นสิ่งนี้จะมอบหมายงาน 6 รายการแทนที่จะเป็น 4 รายการที่คุณมีหากคุณติดตั้งเทมเพลตสามรอบด้วยตัวเองแม้ว่าฉันหวังว่าคอมไพเลอร์จะแก้ปัญหานั้นสำหรับประเภทง่ายๆ

คุณสามารถสร้างสถานการณ์ที่สว็อปเทอะทะหรือไม่เหมาะสมตัวอย่างเช่น

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

ค่อนข้างอึดอัดในการแกะกล่อง

อย่างไรก็ตามประเด็นคือมีวิธีที่ทราบกันดีในการจัดการกับสถานการณ์ที่พบบ่อยที่สุดที่สิ่งเหล่านี้เป็นสิ่งที่ดีและด้วยเหตุนี้จึงไม่มีความเร่งด่วนที่ดีในการรับมือกับสิ่งที่เกิดขึ้น หากไม่มีสิ่งอื่นใดฉันไม่มั่นใจว่า:

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

ไม่ทำสำเนา 6 ชุดทำให้ไม่เหมาะสมอย่างยิ่งสำหรับบางประเภท (คอลเล็กชันจะชัดเจนที่สุด) อย่าลังเลที่จะชักชวนฉันว่าสิ่งที่ดึงดูดเป็นความคิดที่ดีสำหรับประเภท "ใหญ่" โดยบอกว่าสิ่งนี้ไม่ใช่ :-)

สำหรับการส่งคืนค่าหลายค่า tuples จะสมบูรณ์แบบหากค่าเป็นประเภทที่เข้ากันไม่ได้ แต่บางคนไม่ชอบหากเป็นไปได้ที่ผู้โทรจะทำให้ผิดลำดับ บางคนไม่ชอบค่าส่งคืนหลายค่าเลยและไม่ต้องการส่งเสริมให้ใช้โดยทำให้ง่ายขึ้น บางคนชอบโครงสร้างที่มีชื่อสำหรับพารามิเตอร์เข้าและออกและอาจไม่สามารถชักชวนให้ใช้ไม้เบสบอลเพื่อใช้ทูเปิลได้ ไม่มีการบัญชีสำหรับรสชาติ


1
คุณคงไม่ต้องการสลับเวกเตอร์กับทู ฉันคิดว่าการแลกเปลี่ยนองค์ประกอบสามอย่างนั้นชัดเจนกับสิ่งที่เพิ่มขึ้นมากกว่าการแลกเปลี่ยนสองครั้ง สำหรับค่าที่ส่งคืนหลายค่าพารามิเตอร์ออกเป็นสิ่งที่ชั่วร้ายโครงสร้างเป็นการพิมพ์พิเศษและมีบางกรณีที่ต้องการค่าส่งคืนหลายค่า
Zifre

รู้ว่าทำไมคุณถึงใช้ tuples (และฉันรู้ว่าทำไมฉันถึงใช้มันถ้ามีโอกาสเกิดขึ้นแม้ว่าฉันจะไม่คิดว่ามันเคยมี) ฉันเดาว่าทำไมคนอื่นถึงไม่ใช้แม้ว่าพวกเขาจะรู้ เช่นเพราะพวกเขาไม่เห็นด้วยกับ "out params are evil" ...
Steve Jessop

คุณรู้หรือไม่ว่าเราสามารถแทนที่ "tie (a, b, c) = make_tuple (b, c, a);" โดย "tie (a, b, c) = tie (b, c, a);" ?
Rexxar

2
เน็คไท (ในทางเทคนิคระดับหนึ่ง) คือทูเพิลที่สร้างขึ้นด้วยการอ้างอิงที่ไม่ใช่คอนส ฉันไม่พบเอกสารการเพิ่มที่ระบุว่าสิ่งที่รับประกันตัวดำเนินการ = และตัวสร้างสำเนาสำหรับการผูก / ทูเปิลทำเมื่อการอ้างอิงบางส่วนที่เกี่ยวข้องมีการอ้างอิงเดียวกัน แต่นั่นคือสิ่งที่คุณต้องรู้ การใช้งานตัวดำเนินการที่ไร้เดียงสา = อาจผิดพลาดได้อย่างชัดเจน ...
Steve Jessop

1
@ สตีฟ: และเนื่องจากความสัมพันธ์ล้วนเกี่ยวกับการป้องกันการทำสำเนา (ควรใช้กับประเภทที่ไม่สามารถคัดลอกได้โปรดทราบว่า LHS อาจเป็นอย่างอื่นทั้งหมด) แน่นอนว่าทุกอย่างควรผิดพลาดอย่างมาก (นึกถึงอ็อบเจ็กต์คลาสที่ไม่ใช่ POD) ลองนึกดูว่าคุณจะเขียนตรรกะเดียวกันโดยไม่ใช้อุณหภูมิได้อย่างไร
sehe

8

อย่างที่หลาย ๆ คนชี้ให้เห็นสิ่งที่เพิ่มขึ้นนั้นไม่ได้มีประโยชน์เท่าคุณสมบัติอื่น ๆ

  1. ลูกเล่นการสลับและหมุนเป็นเพียงลูกเล่น พวกเขาสร้างความสับสนให้กับผู้ที่ไม่เคยเห็นมาก่อนและเนื่องจากมีทุกคนค่อนข้างมากลูกเล่นเหล่านี้เป็นเพียงการปฏิบัติทางวิศวกรรมซอฟต์แวร์ที่ไม่ดี

  2. การส่งคืนค่าหลายค่าโดยใช้ tuples เป็นการจัดทำเอกสารในตัวเองน้อยกว่ามากจากนั้นทางเลือกอื่น ๆ - ส่งคืนประเภทที่มีชื่อหรือใช้การอ้างอิงที่มีชื่อ หากไม่มีการจัดทำเอกสารด้วยตนเองนี้จะง่ายต่อการสับสนลำดับของค่าที่ส่งคืนหากสามารถเปลี่ยนแปลงได้ร่วมกันและไม่ฉลาดกว่านี้


6

ไม่ใช่ทุกคนที่สามารถใช้ boost ได้และ TR1 ยังไม่สามารถใช้งานได้ในวงกว้าง


3
ผู้คนจำนวนมากใช้ Boost คนเหล่านั้นสามารถใช้ tuples ด้วย
Zifre

3
คุณถามว่าทำไมคนไม่ใช้พวกเขาและฉันก็ให้คำตอบเดียว
Brian Neal

2
สำหรับผู้ลงคะแนนเสียง: ฉันบังเอิญทำงานในสถานที่ที่ไม่สามารถใช้บูสต์ทางการเมืองได้และแม้กระทั่ง ณ วันนี้โซ่เครื่องมือคอมไพเลอร์ที่เราใช้ (สำหรับระบบฝังตัว) ไม่มีการรองรับ TR1 / C ++ 11
Brian Neal

5

เมื่อใช้ C ++ บนระบบฝังตัวการดึงไลบรารี Boost จะซับซ้อน พวกเขาเชื่อมต่อกันดังนั้นขนาดห้องสมุดจึงใหญ่ขึ้น คุณส่งคืนโครงสร้างข้อมูลหรือใช้การส่งผ่านพารามิเตอร์แทนทูเปิล เมื่อคืนค่า tuples ใน Python โครงสร้างข้อมูลจะอยู่ในลำดับและประเภทของค่าที่ส่งคืนซึ่งไม่ชัดเจน


5

คุณไม่ค่อยเห็นพวกเขาเนื่องจากโค้ดที่ออกแบบมาอย่างดีมักจะไม่ต้องการ - มีไม่มากในหลาย ๆ กรณีในไวลด์ที่การใช้โครงสร้างแบบไม่ระบุตัวตนนั้นดีกว่าการใช้โค้ดที่มีชื่อ เนื่องจาก tuple ทั้งหมดเป็นตัวแทนของโครงสร้างที่ไม่ระบุตัวตนจริงๆ coders ส่วนใหญ่ในสถานการณ์ส่วนใหญ่ก็ไปกับของจริง

สมมติว่าเรามีฟังก์ชัน "f" ซึ่งการคืนค่าทูเพิลอาจสมเหตุสมผล ตามกฎทั่วไปฟังก์ชันดังกล่าวมักจะซับซ้อนพอที่จะล้มเหลวได้

หาก "f" สามารถล้มเหลวคุณต้องมีการคืนสถานะหลังจากนั้นคุณไม่ต้องการให้ผู้โทรตรวจสอบทุกพารามิเตอร์เพื่อตรวจจับความล้มเหลว "f" อาจเหมาะกับรูปแบบ:

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...
}

นั่นไม่สวย แต่ดูว่าทางเลือกนั้นน่าเกลียดแค่ไหน โปรดทราบว่าฉันยังต้องการค่าสถานะ แต่รหัสไม่สามารถอ่านได้อีกต่อไปและไม่สั้นลง มันอาจจะช้ากว่าเช่นกันเนื่องจากฉันต้องเสียค่าใช้จ่าย 1 สำเนาพร้อมทูเพิล

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 ...
}

ข้อเสียที่สำคัญอีกประการหนึ่งซ่อนอยู่ในที่นี่ด้วย "ReturnInts" ฉันสามารถเพิ่มการเปลี่ยนแปลงผลตอบแทนของ "f" ได้โดยการแก้ไข "ReturnInts" โดยไม่ต้องแก้ไข INTERFACE ของ "f" โซลูชันทูเพิลไม่ได้นำเสนอคุณลักษณะที่สำคัญซึ่งทำให้เป็นคำตอบที่ด้อยกว่าสำหรับโค้ดไลบรารีใด ๆ


1
ข้อยกเว้นทำให้อินเทอร์เฟซนั้นสะอาดขึ้นมาก
David Stone

เพื่อความเป็นธรรม (และล่าช้ามากสำหรับงานปาร์ตี้) คุณสามารถอ่านได้ง่ายขึ้นโดยการตั้งค่าusing std::tuple;และใช้tupleในรหัส
Alrekr

2
การใช้tupleทำให้โค้ดอ่านได้น้อยลงไม่มาก รหัสส่วนใหญ่ในปัจจุบันมีสัญลักษณ์จำนวนมาก - การมองเห็นstd::tupleทำให้เห็นได้ชัดเจนว่ามันคืออะไร
Tom Swirly

3

สิ่งเหล่านี้มีประโยชน์อย่างแน่นอน แต่ดังที่ได้กล่าวไปแล้วมีค่าใช้จ่ายเล็กน้อยและมีอุปสรรคหนึ่งหรือสองอย่างที่คุณต้องข้ามผ่านก่อนที่คุณจะสามารถใช้งานได้จริง

หากโปรแกรมของคุณพบสถานที่ที่คุณต้องส่งคืนค่าหลายค่าหรือสลับค่าหลายค่าอยู่เสมออาจเป็นการคุ้มค่าที่จะไปตามเส้นทางทูเพิล แต่บางครั้งการทำสิ่งต่าง ๆ แบบคลาสสิกก็ง่ายกว่า

โดยทั่วไปไม่ใช่ทุกคนที่ติดตั้ง Boost ไว้แล้วและแน่นอนว่าฉันจะไม่ต้องยุ่งยากกับการดาวน์โหลดและกำหนดค่าไดเร็กทอรีรวมของฉันให้ใช้งานได้กับสิ่งอำนวยความสะดวกแบบทูเพิลเท่านั้น ฉันคิดว่าคุณจะพบว่าผู้คนที่ใช้ Boost อยู่แล้วมักจะพบการใช้ทูเปิลในโปรแกรมของตนมากกว่าผู้ใช้ที่ไม่ได้ใช้ Boost และผู้ย้ายถิ่นจากภาษาอื่น ๆ (Python อยู่ในใจ) มีแนวโน้มที่จะไม่พอใจกับการขาด tuples ใน C ++ เพื่อสำรวจวิธีการเพิ่มการสนับสนุนทูเพิล


1

เนื่องจากที่เก็บข้อมูลstd::tupleมีลักษณะที่เลวร้ายที่สุดของทั้ง a structและอาร์เรย์ การเข้าถึงทั้งหมดขึ้นอยู่กับตำแหน่งที่ n แต่ไม่สามารถวนซ้ำผ่านการtupleใช้forลูปได้

ดังนั้นถ้าองค์ประกอบในtupleแนวคิดเป็นอาร์เรย์ฉันจะใช้อาร์เรย์และถ้าองค์ประกอบนั้นไม่ใช่อาร์เรย์ตามแนวคิดโครงสร้าง (ซึ่งมีชื่อองค์ประกอบ) จะสามารถบำรุงรักษาได้มากกว่า ( a.lastnameอธิบายได้มากกว่าstd::get<1>(a))

สิ่งนี้ทำให้การเปลี่ยนแปลงที่ OP กล่าวถึงเป็นเพียงกรณีการใช้งานที่ใช้ได้สำหรับทูเปิล


0

ฉันมีความรู้สึกว่าหลายคนใช้ Boost.Any และ Boost.Variant (ด้วยวิศวกรรมบางอย่าง) แทน Boost.Tuple


ทำไมคุณถึงแลกเปลี่ยนการพิมพ์แบบคงที่ที่มีประสิทธิภาพสำหรับสิ่งเหล่านี้?
Zifre

Boost.Variant เป็นประเภทที่ปลอดภัยอย่างสมบูรณ์
user21714

1
อ๊ะใช่เป็น typesafe แต่พิมพ์รันไทม์
Zifre

5
ฉันไม่เห็นว่า Tuple สามารถแทนที่ Any / Variant ได้อย่างไร พวกเขาไม่ได้ทำสิ่งเดียวกัน
Mankarse

1
@ Zifre ฉันไม่สามารถพูดแทนผู้เขียนได้ แต่ฉันคิดว่าความหมายที่นี่คือการใช้ร่วมกับคอนเทนเนอร์ประเภทอื่น ๆ
Tim Seguine
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.