เครื่องมือสร้างช่วงเวกเตอร์สามารถเรียกการแปลงที่ชัดเจนได้หรือไม่


14

โปรแกรมต่อไปนี้มีรูปแบบที่ดีหรือไม่

#include <vector>
struct A {
    explicit A(int) {}
};
int main() {
    std::vector<int> vi = {1, 2, 3, 4, 5};
    std::vector<A> va(vi.begin(), vi.end());
}

ตาม C ++ 17 [sequence.reqmts] ข้อกำหนดสำหรับ

X u(i, j);

โดยที่Xเป็นคอนเทนเนอร์ลำดับคือ:

Tจะต้องEmplaceConstructibleเข้ามาจากX*i

อย่างไรก็ตามในวรรคก่อนมีการระบุว่า:

iและjiterators แสดงว่าความพึงพอใจของข้อกำหนดของข้อมูล iterator และการอ้างอิงถึงองค์ประกอบโดยปริยายแปลงสภาพให้แก่value_type,

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

แต่น่าแปลกใจที่ดูเหมือนว่าจะรวบรวมภายใต้ GCC


(สำหรับบันทึกนี้ไม่เพียง gcc: godbolt.org/z/ULeRDw )
Max Langhof

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

คำตอบ:


2

มันเป็นเพียงข้อกำหนดสำหรับตู้คอนเทนเนอร์ตามลำดับเพื่อสนับสนุนการก่อสร้างจากตัววนซ้ำที่ตอบสนองเกณฑ์การแปลงสภาพโดยนัย

นี้ไม่ได้ด้วยตัวเองไม่อนุญาตภาชนะลำดับจากการสนับสนุนการก่อสร้างจาก iterators ที่ไม่ตรงตามเกณฑ์ที่เท่าที่ผมสามารถบอกได้1 มีกฎที่ชัดเจนเกี่ยวกับเรื่องนี้:

ถ้า Constructor ... ถูกเรียกด้วย InputIterator ประเภทที่ไม่เข้าข่ายเป็นตัววนซ้ำอินพุต Constructor จะไม่เข้าร่วมในการแก้ปัญหาการโอเวอร์โหลด

มันไม่ชัดเจนว่า "มีคุณสมบัติเป็นตัววนซ้ำอินพุต" หมายถึงอะไรในบริบท มันเป็นวิธีที่ไม่เป็นทางการในการแสดง Cpp17InputIterator หรือพยายามอ้างถึงข้อกำหนดของ i และ j หรือไม่? ฉันไม่รู้ ไม่ว่าจะอนุญาตหรือไม่ก็ตามมาตรฐานไม่มีข้อกำหนดที่เข้มงวดในการตรวจจับ:

[container.requirements.general]

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

ด้วยการตีความว่า Cpp17InputIterator ใด ๆ "มีคุณสมบัติเป็นตัวทำซ้ำอินพุต" โปรแกรมตัวอย่างจะไม่จำเป็นต้องมีรูปแบบที่ไม่ดี แต่ไม่รับประกันว่าจะมีรูปแบบที่ดีเช่นกัน

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


PS นี้รวบรวมโดยไม่มีคำเตือนใน Clang (พร้อม libc ++) และ Msvc เช่นกัน

PPS ถ้อยคำนี้ดูเหมือนจะถูกเพิ่มเข้าไปใน C ++ 11 (ซึ่งเป็นเรื่องธรรมดา


1
ขึ้นอยู่กับสิ่งที่"ไม่เข้าข่ายว่าเป็นตัววนซ้ำอินพุต"หมายถึงอะไรจริงๆ ต่างจากข้างต้นจริง ๆ แล้วมันไม่ได้พูดCpp17InputIteratorดังนั้นจึงไม่ชัดเจนสำหรับฉันว่า"และอ้างถึงองค์ประกอบที่แปลงสภาพโดยปริยายเป็นvalue_type"รวมอยู่ใน "input iterator" ถ้าเป็นเช่นนั้นตัวสร้างไม่ควรมีส่วนร่วมในการแก้ปัญหาการโอเวอร์โหลดและโปรแกรมควรจะมีรูปแบบไม่ดี
Max Langhof

1
ดังนั้นทุกไลบรารี่มาตรฐานจะได้รับอนุญาตให้มีคอนสตรัคเตอร์พิเศษโดยไม่ต้องทำการวินิจฉัยเมื่อใช้คอนสตรัคเตอร์พิเศษเหล่านั้นหรือไม่ ที่สังหรณ์ใจดูเหมือนว่าผิดที่ฉัน ...
ไบรอัน

@ ไบรอันฉันไม่แน่ใจว่ามันเป็น "ตัวสร้างพิเศษ" แต่อาจจะมากกว่า "การใช้งานเฉพาะของตัวสร้างที่อนุญาตให้มีพื้นที่มากขึ้น" การตรวจสอบอินพุตทุกตัวอาจส่งผลกระทบต่อประสิทธิภาพการทำงานอย่างมากดังนั้นฉันจึงไม่รู้ว่าจะเป็นวิธีที่จะไปหรือไม่ ...
JHBonarius

@Brian แน่นอนมันจะเป็นความคิดที่ไม่ดีแม้ว่าจะไม่ได้รับอนุญาตอย่างชัดเจนก็ตาม ในกรณีนี้เราจะพิจารณาว่าตัวสร้างที่ต้องการได้รับอนุญาตให้สนับสนุนประเภทตัววนซ้ำที่ไม่จำเป็นต้องให้การสนับสนุนหรือไม่ ในกรณีนี้มีข้อกำหนด "จะไม่เข้าร่วม" อย่างชัดเจนตามที่ Max อธิบายซึ่งจะไม่อนุญาตสิ่งนี้อย่างแน่นอน แต่แท้จริงแล้วยังไม่ชัดเจนว่า "มีคุณสมบัติเป็นตัววนซ้ำอินพุต" หมายถึงอะไรในบริบท มันเป็นวิธีที่ไม่เป็นทางการในการแสดงCpp17InputIteratorหรือมันพยายามอ้างถึงข้อกำหนดของiและj? ฉันไม่รู้
eerorika

2
1) ใน C ++ เราตั้งค่าต่ำมาตรฐาน . 2) การก่อสร้างที่มีฟังก์ชั่นที่ไม่ใช่สมาชิกเสมือน 3) ดูLWG 3297 ; อย่างไรก็ตามฉันไม่มั่นใจอย่างยิ่งว่าเราควรลบข้อกำหนดการแปลงโดยนัย
TC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.