ฟังก์ชัน std::make_
ในมาตรฐาน เช่น:
std::make_unique
และstd::make_shared
std::make_tuple
std::make_from_tuple
ทั้งหมดใช้ การเริ่มต้นวงเล็บกลม ภายใน แทนที่จะเป็น วงเล็บปีกกา
ตัวอย่างเช่น make_from_tuple
ตามที่มาตรฐานนำเสนอ เลือกที่จะส่งคืน T(params...)
แทน กว่า T{params...}
ผลลัพธ์ก็คือสิ่งต่อไปนี้ผิดกฎหมาย:
auto vec = std::make_from_tuple<std::vector<int>>(std::make_tuple());
auto arr = std::make_from_tuple<std::array<int, 2>>(std::make_tuple(9, 8));
^การสร้าง std::array
จาก tuple
ดังที่กล่าวข้างต้นคือ ผิดกฎหมายด้วย C++20 เช่น p0960 - อนุญาตให้เริ่มต้นการรวมจากรายการค่าในวงเล็บกลายเป็น เป็นส่วนหนึ่งของ ข้อมูลจำเพาะของ C++20 ไม่อนุญาตให้มีการกำหนดค่าเริ่มต้นดังกล่าวสำหรับ std::array
เนื่องจากประเภทภายในคือ T[size]
ซึ่งไม่สามารถเตรียมใช้งานจากรายการค่าได้ (วงเล็บถูกลบออกด้วยการเริ่มต้น std::array
แล้ว)
ในกรณีที่ใช้งานได้ การเลือกการเริ่มต้นวงเล็บเหลี่ยมเทียบกับวงเล็บปีกกาจะมีความหมาย:
auto vec2 = std::make_from_tuple<std::vector<int>>(std::make_tuple(2, 3));
// a vector with the values: {3, 3} surprise? :-)
(แน่นอนว่าข้างต้นคือ ตัวอย่างของเล่น ทูเพิลที่ให้มาอาจถูกจัดเตรียมไว้ภายนอก)
ด้วยการชอบ curly_make_from_tuple
:
template<typename T, typename tuple_t>
constexpr auto curly_make_from_tuple(tuple_t&& tuple) {
constexpr auto get_T = [](auto&& ... x){ return T{std::forward<decltype(x)>(x) ... }; };
return std::apply(get_T, std::forward<tuple_t>(tuple));
}
ทุกกรณีข้างต้นจะใช้ได้ผล ในลักษณะที่อาจโต้แย้งได้ว่าเป็นธรรมชาติมากกว่า:
auto arr = curly_make_from_tuple<std::array<int, 2>>(std::make_tuple(9, 8)); // {9, 8}
auto vec = curly_make_from_tuple<std::vector<int>>(std::make_tuple()); // {}
auto vec2 = curly_make_from_tuple<std::vector<int>>(std::make_tuple(2, 3)); // {2, 3}
คำถามคือ: เหตุใดมาตรฐานจึงเลือก การเริ่มต้นวงเล็บกลม มากกว่า วงเล็บปีกกา?
ลิงก์ที่เกี่ยวข้อง:
คำถามที่คล้ายกันจากมุมมองด้านประสิทธิภาพ: ทำไม การใช้งาน make_tuple ไม่ส่งคืนผ่านการเริ่มต้นวงเล็บปีกกาใช่ไหม
การสนทนาและคำแนะนำที่ดีสำหรับการเพิ่มการเริ่มต้นวงเล็บปีกกา ตัวเลือกสำหรับ `ยูทิลิตี้ make_`
บทความต้นฉบับเสนอ make_from_tuple
, P0209r2 ดูเหมือนจะไม่พูดถึงสองทางเลือก T(params...)
และ T{params...}
อาจเป็นเพราะวิธีอรรถประโยชน์ make_
ที่คล้ายกันทั้งหมดได้ใช้การเริ่มต้นวงเล็บเหลี่ยมแล้ว
T(std::forward<decltype(x)>(x) ... )
แทนT{std::forward<decltype(x)>(x) ... }
? - person NathanOliver   schedule 26.05.2020std::make_unique
,std::make_shared
,std::make_tuple
ฯลฯ ไม่ได้เตรียมใช้งานสิ่งต่าง ๆ แต่จะส่งคืนอ็อบเจ็กต์และข้อดีของพวกมันคือความปลอดภัยของเธรด ความเรียบง่าย ฯลฯ - person asmmo   schedule 26.05.2020