Skip to content

Instantly share code, notes, and snippets.

@zzxx-husky
Created August 30, 2021 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zzxx-husky/40a42457c01b86f388974a14278dc78e to your computer and use it in GitHub Desktop.
Save zzxx-husky/40a42457c01b86f388974a14278dc78e to your computer and use it in GitHub Desktop.
An attempt to expand the elements of a C++ container into variadic function arguments
// Example program
#include <cstdarg>
#include <cstdio>
#include <stdexcept>
#include <iostream>
#include <list>
// a function that takes n integers and calculate their sum
// 取n个整数并且求和
int sum1(int n, ...) {
int s = 0;
va_list valist;
va_start(valist, n);
for (int i = 0; i < n; i++) {
s += va_arg(valist, int);
}
va_end(valist);
return s;
}
const int MaxN = 10;
// 如果元素的数目达到了MaxN,报错
template<int cnt>
std::enable_if_t<cnt == MaxN, int>
translate(...) {
throw std::runtime_error("The number of elements in the container must be less than MaxN.");
}
// 从container一个个元素取出来放到args里面。递归,每次取一个。
template<int cnt, typename T, typename ... ArgT>
std::enable_if_t<cnt < MaxN, int>
translate(T&& left, T&& right, ArgT&& ... args) {
if (left == right) {
// 如果全取出来,传到sum1
return sum1(cnt, std::forward<ArgT>(args) ...);
}
auto next = *left;
return translate<cnt + 1>(std::forward<T>(++left), std::forward<T>(right), std::forward<ArgT>(args) ..., next);
}
// calculate the sum of the elements in the container `any`, assuming the element type is int.
// 计算一个container里面所有元素的和,这里默认都是int
template<typename T>
int sum2(T&& any) {
return translate<0>(any.begin(), any.end());
}
int main()
{
std::cout << sum1(3, 1, 2, 3) << std::endl; // 1 + 2 + 3 = 6
std::cout << sum2(std::list<int>{1, 2, 3}) << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment