อะไรคือความแตกต่างระหว่างแนวคิดและข้อ จำกัด ของเทมเพลต


96

ฉันต้องการทราบว่าอะไรคือความแตกต่างทางความหมายระหว่างข้อเสนอแนวคิดเต็มรูปแบบ C ++ และข้อ จำกัด ของเทมเพลต (ตัวอย่างเช่นข้อ จำกัด ที่ปรากฏใน Dlang หรือ ข้อเสนอแนวคิดใหม่สำหรับ C ++ 1y )

แนวคิดที่สมบูรณ์สามารถทำอะไรได้มากกว่าข้อ จำกัด ของเทมเพลตที่ไม่สามารถทำได้


2
ข้อเสนอข้อ จำกัดจะรวมอยู่ในนี้
chris

ฉันนึกถึง4.8 แนวคิดการออกแบบแต่จริงๆแล้วไม่ค่อยมีการระบุไว้มากนักว่าแนวคิดนี้มีข้อ จำกัด อย่างไร ถ้ามีอะไรตอนนี้แนวคิดของ Googling อาจเผยให้เห็นความแตกต่างที่เห็นได้ง่ายหลังจากได้รับความเข้าใจที่ดีขึ้นเกี่ยวกับข้อ จำกัด จากข้อเสนอ
chris

แนวคิดของ IMHO ช่วยเพิ่มความสามารถในการอ่านและให้ความสามารถในการเขียนโปรแกรมที่ชัดเจนขึ้นตามที่ Alexander Stepanov ชอบใน 'Elements of Programming' ข้อเสนอ Lite เป็นเพียงการก้าวไปสู่สิ่งนี้เพื่อลดภาระของข้อ จำกัด ประเภท enable_if แปลก ๆ ที่จำเป็นในขณะนี้ ยิ่งเร็วยิ่งดีสำหรับการเขียนโปรแกรมทั่วไป
dirvine

คำตอบ:


136

ข้อมูลต่อไปนี้ล้าสมัย จำเป็นต้องได้รับการอัปเดตตามแบบร่าง Concepts Lite ล่าสุด

ส่วนที่ 3 ของข้อเสนอข้อ จำกัดครอบคลุมประเด็นนี้ในเชิงลึกที่สมเหตุสมผล

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

ในการออกแบบ Concept Libraries สำหรับ C ++ Sutton และ Stroustrup พิจารณาความสัมพันธ์ต่อไปนี้:

แนวคิด = ข้อ จำกัด + สัจพจน์

สรุปความหมายได้อย่างรวดเร็ว:

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

ดังนั้นหากคุณเพิ่มสัจพจน์ (คุณสมบัติทางความหมาย) ในข้อ จำกัด (คุณสมบัติทางวากยสัมพันธ์) คุณจะได้รับแนวคิด


Concepts-Lite

ข้อเสนอแนวความคิดนำเสนอเฉพาะส่วนแรกข้อ จำกัด เท่านั้น แต่นี่เป็นขั้นตอนที่สำคัญและจำเป็นต่อแนวคิดที่ครบถ้วนสมบูรณ์

ข้อ จำกัด

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

มาดูข้อ จำกัด ในการดำเนินการ:

template <typename Cont>
  requires Sortable<Cont>()
void sort(Cont& container);

sortที่นี่เราจะกำหนดแม่แบบฟังก์ชั่นที่เรียกว่า นอกจากนี้ใหม่เป็นต้องใช้ประโยค ประโยคต้องการให้ข้อ จำกัด บางประการเกี่ยวกับอาร์กิวเมนต์แม่แบบสำหรับฟังก์ชันนี้ โดยเฉพาะข้อ จำกัด นี้บอกว่าประเภทContต้องเป็นSortableประเภท สิ่งที่เรียบร้อยคือสามารถเขียนในรูปแบบที่กระชับมากขึ้นเป็น:

template <Sortable Cont>
void sort(Cont& container);

ตอนนี้ถ้าคุณพยายามส่งผ่านอะไรก็ตามที่ไม่ได้รับการพิจารณาSortableให้ใช้ฟังก์ชันนี้คุณจะได้รับข้อผิดพลาดที่แจ้งให้คุณทราบทันทีว่าประเภทที่อนุมานสำหรับTไม่ใช่Sortableประเภท ถ้าคุณได้ทำใน C ++ 11 คุณจะมีข้อผิดพลาดที่น่ากลัวบางอย่างโยนลงมาจากภายในsortฟังก์ชั่นที่ทำให้รู้สึกไม่ให้ใคร

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

  1. ประเภทนี้มีตัวดำเนินการดังกล่าวมากเกินไปหรือไม่?
  2. ประเภทเหล่านี้สามารถใช้เป็นตัวถูกดำเนินการกับตัวดำเนินการนี้ได้หรือไม่
  3. ประเภทนี้มีลักษณะเช่นนี้หรือไม่?
  4. นิพจน์คงที่นี้เท่ากับหรือไม่? (สำหรับอาร์กิวเมนต์แม่แบบที่ไม่ใช่ประเภท)
  5. ประเภทนี้มีฟังก์ชันที่เรียกว่า yada-yada ที่ส่งกลับประเภทนั้นหรือไม่?
  6. ประเภทนี้ตรงตามข้อกำหนดทางวากยสัมพันธ์ทั้งหมดที่จะใช้ตามนั้นหรือไม่

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

ตัวอย่าง

ดังนั้นสิ่งที่สำคัญเกี่ยวกับข้อ จำกัด ก็คือพวกเขาไม่สนใจเกี่ยวกับความหมายหนึ่ง iota ตัวอย่างที่ดีของข้อ จำกัด ได้แก่ :

  • Equality_comparable<T>: ตรวจสอบว่าประเภทมี==ตัวถูกดำเนินการทั้งสองประเภทเดียวกันหรือไม่

  • Equality_comparable<T,U>: ตรวจสอบว่ามี==ตัวถูกดำเนินการด้านซ้ายและขวาของประเภทที่กำหนดหรือไม่

  • Arithmetic<T>: ตรวจสอบว่าประเภทนั้นเป็นประเภทเลขคณิตหรือไม่

  • Floating_point<T>: ตรวจสอบว่าประเภทนั้นเป็นประเภททศนิยมหรือไม่

  • Input_iterator<T>: ตรวจสอบว่าประเภทสนับสนุนการดำเนินการทางวากยสัมพันธ์ที่ตัววนซ้ำอินพุตต้องรองรับหรือไม่

  • Same<T,U>: ตรวจสอบว่าประเภทที่ระบุเหมือนกันหรือไม่

คุณสามารถลองออกทั้งหมดนี้ด้วยพิเศษสร้างแนวคิด-Lite ของ GCC


นอกเหนือจาก Concepts-Lite

ตอนนี้เราเข้าสู่ทุกสิ่งนอกเหนือจากข้อเสนอแนวความคิด นี่เป็นอนาคตที่ยิ่งใหญ่กว่าอนาคต ทุกอย่างต่อจากนี้ไปมีแนวโน้มที่จะเปลี่ยนแปลงไม่น้อย

สัจพจน์

สัจพจน์ทั้งหมดเกี่ยวกับความหมาย พวกเขาระบุความสัมพันธ์ความไม่แน่นอนการรับประกันความซับซ้อนและสิ่งอื่น ๆ ลองดูตัวอย่าง

แม้ว่าEquality_comparable<T,U>ข้อ จำกัด จะบอกคุณว่ามีoperator== ประเภทที่ต้องใช้TและUแต่ก็ไม่ได้บอกคุณว่าการดำเนินการนั้นหมายถึงอะไร Equivalence_relationเพื่อที่เราจะมีความจริง สัจพจน์นี้กล่าวว่าเมื่อเปรียบเทียบวัตถุทั้งสองประเภทกับการoperator==ให้trueแล้ววัตถุเหล่านี้จะเทียบเท่ากัน สิ่งนี้อาจดูเหมือนซ้ำซ้อน แต่ก็ไม่แน่นอน คุณสามารถกำหนดได้อย่างง่ายดายoperator==ว่าแทนที่จะทำตัวเหมือนoperator<ไฟล์. คุณเป็นคนชั่วที่ทำแบบนั้น แต่คุณทำได้

อีกตัวอย่างหนึ่งคือGreaterสัจพจน์ มันเป็นเรื่องที่ดีและดีที่จะพูดวัตถุสองชนิดTสามารถนำมาเปรียบเทียบกับ>และ<ผู้ประกอบการ แต่สิ่งที่พวกเขาหมายถึง ? Greaterความจริงบอกว่า IFF xเป็นใหญ่แล้วyจากนั้นก็จะน้อยกว่าy xข้อกำหนดที่เสนอเช่นสัจพจน์มีลักษณะดังนี้:

template<typename T>
axiom Greater(T x, T y) {
  (x>y) == (y<x);
}

สัจพจน์จึงตอบคำถามประเภทต่อไปนี้:

  1. ตัวดำเนินการทั้งสองนี้มีความสัมพันธ์ซึ่งกันและกันหรือไม่?
  2. ตัวดำเนินการสำหรับประเภทดังกล่าวหมายถึงสิ่งนี้หรือไม่
  3. การดำเนินการในประเภทนั้นมีความซับซ้อนขนาดนี้หรือไม่?
  4. ผลลัพธ์นี้ของตัวดำเนินการนั้นบ่งบอกว่าเป็นจริงหรือไม่?

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

ตัวอย่าง

นี่คือตัวอย่างทั่วไปของสัจพจน์:

  • Equivalence_relation: ถ้าวัตถุสองชิ้นเปรียบเทียบ==กันจะมีค่าเท่ากัน

  • Greater: เมื่อใดก็ตามแล้วx > yy < x

  • Less_equal: เมื่อใดก็ตามแล้วx <= y!(y < x)

  • Copy_equality: สำหรับxและyประเภทT: if x == yออบเจ็กต์ใหม่ประเภทเดียวกันที่สร้างขึ้นโดยการสร้างสำเนาT{x} == yและยังคงอยู่x == y(นั่นคือไม่ทำลาย)

แนวคิด

ตอนนี้แนวคิดง่ายมากที่จะกำหนด พวกเขาเป็นเพียงการรวมกันของข้อ จำกัด และหลักการ พวกเขาให้ข้อกำหนดที่เป็นนามธรรมเหนือไวยากรณ์และความหมายของประเภท

ตัวอย่างเช่นพิจารณาOrderedแนวคิดต่อไปนี้:

concept Ordered<Regular T> {
  requires constraint Less<T>;
  requires axiom Strict_total_order<less<T>, T>;
  requires axiom Greater<T>;
  requires axiom Less_equal<T>;
  requires axiom Greater_equal<T>;
}

โน้ตตัวแรกที่สำหรับประเภทแม่แบบTจะเป็นOrderedก็ยังต้องตอบสนองความต้องการของRegularแนวคิด Regularแนวคิดเป็นความต้องการขั้นพื้นฐานมากว่าประเภทที่มีความประพฤติดี - มันสามารถสร้างทำลายคัดลอกและเมื่อเทียบกับ

นอกเหนือจากข้อกำหนดเหล่านั้นข้อกำหนดOrderedที่เป็นTไปตามข้อ จำกัด หนึ่งข้อและสัจพจน์สี่ประการ:

  • ข้อ จำกัด : Orderedประเภทต้องมีoperator<. สิ่งนี้ได้รับการตรวจสอบแบบคงที่ดังนั้นจึงต้องมีอยู่
  • สัจพจน์: สำหรับxและyประเภทT:
    • x < y ให้การสั่งซื้อรวมที่เข้มงวด
    • เมื่อxมีค่ามากกว่าy, yน้อยกว่าxและในทางกลับกัน
    • เมื่อxมีค่าน้อยกว่าหรือเท่ากับy, yไม่ได้น้อยกว่าxและในทางกลับกัน
    • เมื่อxมากกว่าหรือเท่ากับy, yไม่มากกว่าxและในทางกลับกัน

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

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

ตัวอย่าง

นี่คือตัวอย่างบางส่วนของแนวคิด:

  • Regular ประเภทสามารถสร้างได้ทำลายล้างคัดลอกได้และสามารถเปรียบเทียบได้

  • Orderedประเภทการสนับสนุนoperator<และมีการสั่งซื้อรวมที่เข้มงวดและความหมายการสั่งซื้ออื่น ๆ

  • Copyableประเภทที่มีการคัดลอก constructable, destructable และถ้าxมีค่าเท่ากับyและมีการคัดลอกสำเนายังจะเปรียบเทียบเท่ากับxy

  • Iteratorประเภทต้องมีประเภทที่เกี่ยวข้องvalue_type, reference, difference_typeและiterator_categoryที่ตัวเองจะต้องตอบสนองแนวความคิดบางอย่าง นอกจากนี้ยังต้องสนับสนุนoperator++และสามารถอ้างอิงได้

เส้นทางสู่แนวคิด

ข้อ จำกัด เป็นขั้นตอนแรกสู่คุณลักษณะแนวคิดทั้งหมดของ C ++ ขั้นตอนเหล่านี้เป็นขั้นตอนที่สำคัญมากเนื่องจากมีข้อกำหนดที่บังคับใช้แบบคงที่ของประเภทเพื่อให้เราสามารถเขียนฟังก์ชันเทมเพลตและคลาสที่สะอาดกว่ามาก ตอนนี้เราสามารถหลีกเลี่ยงความยากลำบากและความอัปลักษณ์ของstd::enable_ifเพื่อนร่วมโปรแกรม metaprogramming ได้แล้ว

อย่างไรก็ตามมีหลายสิ่งที่ข้อเสนอข้อ จำกัด ไม่ได้ทำ:

  1. ไม่มีภาษานิยามแนวคิด

  2. ข้อ จำกัด ไม่ใช่แผนผังความคิด ผู้ใช้ไม่จำเป็นต้องใส่คำอธิบายประกอบประเภทของตนโดยเฉพาะเนื่องจากเป็นไปตามข้อ จำกัด บางประการ มีการตรวจสอบแบบคงที่โดยใช้คุณสมบัติภาษาคอมไพล์ไทม์อย่างง่าย

  3. การนำเทมเพลตไปใช้ไม่ได้ถูก จำกัด โดยข้อ จำกัด ของอาร์กิวเมนต์เทมเพลต นั่นคือถ้าเทมเพลตฟังก์ชันของคุณทำอะไรกับวัตถุประเภท จำกัด ที่ไม่ควรทำคอมไพลเลอร์จะไม่มีทางวินิจฉัยสิ่งนั้นได้ ข้อเสนอแนวคิดที่มีคุณลักษณะครบถ้วนจะสามารถทำได้

ข้อเสนอข้อ จำกัด ได้รับการออกแบบมาโดยเฉพาะเพื่อให้สามารถนำข้อเสนอแนวคิดฉบับเต็มมาใช้ ด้วยความโชคดีการเปลี่ยนแปลงนั้นควรจะเป็นไปอย่างราบรื่น กลุ่มแนวคิดต้องการแนะนำข้อ จำกัด สำหรับ C ++ 14 (หรือในรายงานทางเทคนิคหลังจากนั้นไม่นาน) ในขณะที่แนวคิดทั้งหมดอาจเริ่มปรากฏในช่วงเวลาประมาณ C ++ 17


5
ควรสังเกตว่า concept-lite ไม่ได้ตรวจสอบข้อ จำกัด ในการใช้งานเทมเพลต ดังนั้นคุณสามารถอ้างว่าสามารถใช้ DefaultConstructable ใด ๆ ได้ แต่คอมไพเลอร์จะไม่หยุดคุณจากการใช้ตัวสร้างการคัดลอกโดยไม่ได้ตั้งใจ ข้อเสนอแนวคิดที่มีคุณลักษณะครบถ้วนมากขึ้นจะ
Nicol Bolas

24
นั่นคือร่างแรก?!
Nicol Bolas

2
@sftrabbit ตอบดีมาก. แต่ฉันมีคำถาม: คอมไพเลอร์จะตรวจสอบได้อย่างไรว่าประเภทนั้นตรงตามข้อกำหนดทางความหมายของแนวคิดหรือไม่?
Rayniery

1
จะ (มีความไม่แน่นอนมาก) 'สัจพจน์' จะถูกตรวจสอบระหว่างรันไทม์หรือจะทำหน้าที่เป็นแท็กสัญญาเท่านั้น?
Red XIII

4
@ScarletAmaranth: เพราะมันเดือดลงเพื่อพิสูจน์ทฤษฎีบทโดยอัตโนมัติในเวลา จำกัด มีอุปสรรคสองประการดังนี้ 1. การพิสูจน์ทฤษฎีบทใด ๆ ในช่วงเวลา จำกัด ซึ่งยากมากในทางทฤษฎีและเป็นไปไม่ได้ด้วยเทคโนโลยีปัจจุบัน 2. คุณไม่สามารถพิสูจน์สัจพจน์ได้เว้นแต่การพิสูจน์จะขึ้นอยู่กับสัจพจน์อื่น ๆ (ซึ่งในกรณีนี้จะกลายเป็น "ไม่ใช่สัจพจน์" ทางคณิตศาสตร์) สัจพจน์เหล่านี้มีจุดมุ่งหมายเพื่อบอกคอมไพเลอร์ "แน่นอนว่าคุณสามารถย้อนกลับการเปรียบเทียบได้หากคุณเห็นว่ามีประโยชน์ ... " หรือ "ใช่ EmptySet ที่ใช้ในจุดตัดเสมอ ให้ผลลัพธ์เหมือนกัน "
Laurent LA RIZZA

22

ดู "มีอะไร" เกี่ยวกับแนวคิด lite "ในส่วน 2.3 ของรายงานการประชุมและบันทึกการสนทนาของแนวคิดล่าสุด (12 มีนาคม) ซึ่งโพสต์ในวันเดียวกันที่นี่: http://isocpp.org/blog/2013/03 / new-paper-n3576-sg8-concept-teleconference-minutes-2013-03-12-herb-sutter .


4

2 เซ็นต์ของฉัน:

  1. ข้อเสนอแนวคิด-Lite ไม่ได้หมายถึงการทำ "การตรวจสอบประเภท" ของแม่แบบการดำเนินงาน กล่าวคือ Concepts-lite จะตรวจสอบความเข้ากันได้ของอินเทอร์เฟซ (โดยนัย) ที่ไซต์สร้างอินสแตนซ์เทมเพลต การอ้างอิงจากกระดาษ: "concept lite เป็นส่วนขยายของ C ++ ที่อนุญาตให้ใช้เพรดิเคตเพื่อ จำกัด อาร์กิวเมนต์ของเทมเพลต" และนั่นแหล่ะ ไม่ได้บอกว่าเนื้อหาเทมเพลตจะถูกตรวจสอบ (แยก) กับเพรดิเคต นั่นอาจหมายความว่าไม่มีความคิดชั้นหนึ่งของarchtypesเมื่อคุณกำลังพูดถึง concept-lite archtypes ถ้าฉันจำไม่ผิดในข้อเสนอเชิงแนวคิดคือประเภทที่เสนอไม่น้อยและไม่ตอบสนองการใช้งานเทมเพลตอีกต่อไป

  2. concept-lite ใช้ฟังก์ชัน constexpr ที่ได้รับการยกย่องพร้อมกับเคล็ดลับไวยากรณ์เล็กน้อยที่คอมไพเลอร์สนับสนุน ไม่มีการเปลี่ยนแปลงในกฎการค้นหา

  3. โปรแกรมเมอร์ไม่จำเป็นต้องเขียนแผนผังแนวคิด

  4. ในที่สุดก็อ้างอีกครั้ง "ข้อเสนอข้อ จำกัด ไม่ได้ระบุถึงข้อกำหนดเฉพาะหรือการใช้ความหมายโดยตรง แต่มีเป้าหมายที่การตรวจสอบไวยากรณ์เท่านั้น" นั่นหมายความว่าสัจพจน์ไม่อยู่ในขอบเขต (จนถึงตอนนี้)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.