Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

type-safe variadic functions with parameters of same type

I want to use type-safe variadic functions introduced in C++11, but not with different types. A example:

template<typename T>
T maxv(T first, T second) {
  return first > second ? first : second; 
}

template<typename T, typename ... Rest>
T maxv(T first, T second, T ... rest) {
  return maxv(first, maxv(second, rest));
}

The type of all parameters are the same, so it is maybe possible to write something like that:

struct Point { int x,y; };  

template<>
Point maxv(Point first, Point second) {
  return first.x > second.x ? first : second; 
}  

maxv({1, 2}, {3, 4});         // no problem    
maxv({1, 2}, {3, 4}, {5, 6}); // compile error

It compiles with this error in mingw g++4.5:

error: no matching function for call to 'maxv(<brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>)'

Because he do not know that {5, 6} is of type Point. What is the solution?

like image 930
R1tschY Avatar asked Mar 23 '12 17:03

R1tschY


1 Answers

The solution is not to use variadic templates! When used with function templates they are intended to deduce the types of the arguments. That is not what you want to do: you want the arguments to take on the expected type.

I don't have a lot of practical experience with this but you'd want to use initializer lists for this:

Point maxv(std::initializer_list<Point> list) {
    ...
}

You might complain that you can't use this with arbitrary types but then you need to realize that you need to tell somewhere what type are involved. ... And it can be made a template although you'd need to specify the argument type.

like image 79
Dietmar Kühl Avatar answered Oct 13 '22 11:10

Dietmar Kühl