C ++ 11: Số tham số chức năng mẫu đa dạng?


87

Làm cách nào để tôi có thể đếm số lượng đối số cho một hàm mẫu đa dạng?

I E:

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

    ...
}

Cách tốt nhất để thực hiện number_of_argsở trên là gì?


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

21
@ R.MartinhoĐiều chỉnh biểu mẫu "Đăng câu trả lời của bạn" cách cuối trang vài inch. ;)
kay

@ kay-SEisevil Tôi không hiểu tại sao bình luận của bạn có ít lượt ủng hộ hơn bình luận của anh ấy.
Sapphire_Brick

Câu trả lời:


103

Chỉ cần viết cái này:

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

Lưu ý rằng đó nlà một biểu thức hằng số (tức là đã biết tại thời điểm biên dịch), có nghĩa là bạn có thể sử dụng nó khi cần biểu thức hằng số, chẳng hạn như:

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

Lưu ý rằng nếu bạn muốn tính toán kích thước tổng hợp của các loại được đóng gói (trái ngược với số loại trong gói), thì bạn phải làm như sau:

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 > {};

sau đó làm điều này:

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

Trong C ++ 17 (và mới hơn), việc tính toán tổng kích thước của các kiểu đơn giản hơn nhiều bằng cách sử dụng biểu thức gấp :

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

Hy vọng rằng sẽ giúp.


9
+1 Đã học được hai điều; sizeof...constexpr. :)
Qix - MONICA ĐÃ ĐƯỢC HỖN HỢP.

1
Vì vậy, điều này sizeof...thực sự trả về số lượng đối số chứ không phải kích thước lưu trữ kết hợp của tất cả các đối số (giống như sizeoftrên một mảng sẽ)?
panzi

@panzi: Có. sizeof ...(T)trả về số loại được đóng gói T. Nếu bạn muốn tính toán kích thước tổng hợp của các loại được đóng gói, thì bạn phải làm như sau: Ideone.com/udggBk Tôi cũng đã thêm điều này vào câu trả lời của mình.
Nawaz

@panzi: tính toán trong câu trả lời của tôi hiện đã được cải thiện một chút.
Nawaz

2
Với C ++ 17, kích thước tính toán của các loại arg cá nhân bây giờ chúng ta có thể sử dụng các biểu lần return (0 + ... + sizeof(t));
P0W
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.