C ++ 11: จำนวนพารามิเตอร์ฟังก์ชันแม่แบบตัวแปร?


87

ฉันจะนับจำนวนอาร์กิวเมนต์ของฟังก์ชันเทมเพลตตัวแปรได้อย่างไร

กล่าวคือ:

template<typename... T>
void f(const T&... t)
{
    int n = number_of_args(t);

    ...
}

วิธีใดที่ดีที่สุดในการนำไปใช้number_of_argsในข้างต้น


28
sizeof...(T).
R.Martinho Fernandes

22
@ อาร์มาร์ตินโญ่เฟอร์นันด์แบบฟอร์ม "โพสต์คำตอบของคุณ" อยู่ไกลออกไปที่ด้านล่างของหน้า ;)
kay

@ kay-SEisevil ฉันไม่เข้าใจว่าทำไมความคิดเห็นของคุณถึงมีการ
Sapphire_Brick

คำตอบ:


104

เพียงเขียนสิ่งนี้:

const std::size_t n = sizeof...(T); //you may use `constexpr` instead of `const`

โปรดทราบว่าnเป็นนิพจน์คงที่ (เช่นรู้จักกันในเวลาคอมไพล์) ซึ่งหมายความว่าคุณสามารถใช้ในกรณีที่ต้องการนิพจน์คงที่เช่น:

std::array<int,   n>  a; //array of  n elements
std::array<int, 2*n>  b; //array of (2*n) elements

auto middle = std::get<n/2>(tupleInstance);

โปรดทราบว่าหากคุณต้องการคำนวณขนาดรวมของประเภทที่บรรจุ (เมื่อเทียบกับจำนวนประเภทในแพ็ค) คุณจะต้องดำเนินการดังนี้:

template<std::size_t ...>
struct add_all : std::integral_constant< std::size_t,0 > {};

template<std::size_t X, std::size_t ... Xs>
struct add_all<X,Xs...> : 
  std::integral_constant< std::size_t, X + add_all<Xs...>::value > {};

จากนั้นทำสิ่งนี้:

constexpr auto size = add_all< sizeof(T)... >::value;

ใน C ++ 17 (และใหม่กว่า) การคำนวณผลรวมของขนาดของประเภทนั้นง่ายกว่ามากโดยใช้นิพจน์พับ :

constexpr auto size = (sizeof(T) + ...);

หวังว่าจะช่วยได้


9
+1 ได้เรียนรู้สองสิ่ง sizeof...และconstexpr. :)
Qix - MONICA MISTREATED

1
ดังนั้นสิ่งนี้sizeof...จะส่งคืนจำนวนอาร์กิวเมนต์จริง ๆ และไม่ใช่ขนาดพื้นที่เก็บข้อมูลรวมของอาร์กิวเมนต์ทั้งหมด (เช่นเดียวsizeofกับอาร์เรย์)?
panzi

@panzi: ใช่ sizeof ...(T)ผลตอบแทนจำนวนTชนิดบรรจุใน หากคุณต้องการคำนวณขนาดรวมของประเภทแพ็กเกจคุณต้องทำสิ่งนี้: ideone.com/udggBk ฉันได้เพิ่มสิ่งนี้ไว้ในคำตอบของฉันด้วย
Nawaz

@panzi: ตอนนี้การคำนวณในคำตอบของฉันดีขึ้นเล็กน้อย
Nawaz

2
ด้วย C ++ 17 ในการคำนวณขนาดของอาร์กิวเมนต์แต่ละประเภทตอนนี้เราสามารถใช้นิพจน์พับได้ return (0 + ... + sizeof(t));
P0W
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.