Более одной круглой скобки в вызове функции?

У меня есть упражнение, в котором мне нужно написать функцию. Схема функции выглядит

auto add(int a){
}

Мне нужно иметь возможность вызывать эту функцию с несколькими скобками:

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

Но я не могу понять, какую функцию C ++ мне следует использовать в этом случае. Я слышал, что мне следует использовать функторы, но я не знаю, является ли это лучшей идеей в этом случае.

5

Решение

Вы можете сделать это, имея add вернуть функтор, то есть объект, который реализует operator(), Вы можете написать шаблонную версию, которая позволит компилятору определять тип. Попытайся Вот.

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;
}

пример

В этом примере T в конечном итоге решит 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 ----------^

Вот еще один пример, где T будет разрешать 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 ----------^

Явный конструктор

Если вы хотите, чтобы конструктор adder быть explicit Вы также должны немного изменить операторы возврата.

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

Другие решения

Единственное решение, которое приходит мне в голову, это сделать это «добавить» как некоторый объект класса с перегруженным оператором скобок, который будет возвращать новый объект, а затем вызывать новые скобки из него, но вам нужно будет как-то вернуть окончательное значение из него, как какой-то поглотитель

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);
}
};

Но это не кажется чем-то полезным, возможно, есть лучший способ достичь того, что вы хотите получить.

0