More than one parenthesis in a function call?

I have an exercise where I need to write a function. The function diagram looks like

auto add(int a){ } 

I need to be able to call this function with many brackets:

 add(1)(2)(3); // 6 add(1)(2)(3)(4); // 10 add(1)(2)(3)(4)(5); // 15 

But I cannot figure out which C ++ function I should use in this case. I heard that I should use functors, but I do not know if this is the best idea in this case.

+5
source share
2 answers

You can do this if add return functor , i.e. an object that implements operator() . You can write a boilerplate version that allows the compiler to infer the type. Try it here .

 template <class T> struct adder { T val; adder(T a) : val(a) {} template <class T2> auto operator()(T2 a) -> adder<decltype(val + a)> { return val + a; } operator T() const { return val; } }; template <class T> adder<T> add(T a) { return a; } 

Example

In this example, T will eventually resolve double :

 std::cout << add(1)(2.5)(3.1f)(4) << std::endl; // T is int -----^ // T is double ------^ // T is still double -----^ // T is still double ----------^ 

Here is another example where T will be resolved double :

 std::cout << add(1)(2.5f)(3.1)(4) << std::endl; // T is int -----^ // T is float -------^ // T is double ------------^ // T is still double ----------^ 

Explicit constructor

If you want the adder constructor to be explicit , you also need to slightly modify the return statements.

 template <class T> struct adder { T val; explicit adder(T a) : val(a) {} template <class T2> auto operator()(T2 a) -> adder<decltype(val + a)> { return adder<decltype(val + a)>(val + a); } operator T() const { return val; } }; template <class T> adder<T> add(T a) { return adder<T>(a); } 
+17
source

The only solution that comes to my mind is to β€œadd” as some class object with an overloaded parenthesis operator that will return a new object and then call new brackets from it, but you will need to return the final value from it anyway, like some getter functions.

 class Adder{ private: int value; public: Adder():value(0){} Adder(int a):value(a){} int get(){return value;} Adder operator() (int a) { return Adder(value+a); } }; 

But this does not seem to be useful, perhaps there is a better way to accomplish what you want to get.

0
source

Source: https://habr.com/ru/post/1268158/


All Articles