In C++11, variadic templates allows one to call a function with any number of arguments, and the ellipsis operator ...
allows that variadic function to do something to each of those arguments, even if that something isn't the same thing for each argument:
template<typename... Types>
void dummy(Types... ts){} //dummy to allow function calls via parameter expansion
template<typename... Numerics>
void increment5(Numerics&... ns){
dummy(ns+=5 ...); //parameter expansion (need space after 5 because 5. is decimal)
//it means "dummy(ns_first+=5, ns_second+=5, ns_third+=5, etc.)"
}
int main(){
int i = 0;
float f = 1.1;
std::valarray<int> vi = {1,2,3};
increment5(i,f,vi);
cout
<<i<<endl
<<f<<endl
<<vi[0]<<' '<<vi[1]<<' '<<vi[2]<<endl;
}
If we define a heterogenous value array (a list of different number types), we want to be able to do the same kind of thing (being able to add a number to each of its elements). But we have to store the elements as a tuple.
//a class of numbers, possibly different
template<typename... Numerics>
class HeterogeneousValueArray{
private:
tuple<Numerics...> inner;
public:
//initialize the internal vector
HeterogeneousValueArray(Numerics... ns): inner(ns...) {}
};
//Given this function, we don't have to explicitly give the types
//when constructing a HVA
template<typename... Numerics>
HeterogeneousValueArray<Numerics...> HeterogeneousValueArray(Numerics... ns){
return HeterogeneousValueArray<Numerics...>(ns);
}
To call the increment5 operator above, we would need to do a tuple expansion. As I understand it, this solution would require defining helper functions for each function I want to write. We can also define the increment5 recursively, but that, again, requires two function bodies per function.
I believe that programming languages should strive to a design that allows us to write the code we want to write. So this is what I want to write.
template<typename... Numerics>
void increment5(HeterogeneousValueArray<Numerics...>& hva){
increment5(hva.inner... ); //expand a tuple
}
Or this.
template<typename... Numerics>
void increment5(HeterogeneousValueArray<Numerics...>& hva){
dummy((hva.inner+5)... ); //expand a tuple
}
In other words, I want to treat a tuple as a parameter pack.
Of course, "write the code you want to write" is idealistic, and there could be problems implementing any feature. What kind of issues would make this kind of feature not work as intended (ambiguity?), or how would it step on the toes of existing code or features? Or... does it already exist in C++14?