-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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