I come from the python world where I could define a chain of operations and call them in a for loop:
class AddOne:
def __call__(self, x, **common_kwargs):
return x+1
class Stringify:
def __call__(self, x, **common_kwargs):
return str(x)
class WrapNicely:
def __call__(self, s, **common_kwargs):
return "result="+s
data = 42
for operation in [AddOne(), Stringify(), WrapNicely()]:
data = operation(data)
output = data
(Note: the goal is to have complex operations. Ideally, common kwargs could be given)
What would be the equivalent in C++ if the return type can be different after each call?
I'm not sure I could find anything close but I may have search with wrong keywords…
C++ is statically typed, so options here are limited:
std::variant
For the first alternative you could create a class template that executes functions via recursive calls, but it's a bit more complex than your python code:
template<class...Fs>
class Functions
{
std::tuple<Fs...> m_functions;
template<size_t index, class Arg>
decltype(auto) CallHelper(Arg&& arg)
{
if constexpr (index == 0)
{
return std::forward<Arg>(arg);
}
else
{
return std::get<index - 1>(m_functions)(CallHelper<index - 1>(std::forward<Arg>(arg)));
}
}
public:
Functions(Fs...functions)
: m_functions(functions...)
{
}
template<class Arg>
decltype(auto) operator()(Arg&& arg)
{
return CallHelper<sizeof...(Fs)>(std::forward<Arg>(arg));
}
};
int main() {
Functions f{
[](int x) { return x + 1; },
[](int x) { return std::to_string(x); },
[](std::string const& s) { return "result=" + s; }
};
std::cout << f(42) << '\n';
}
Note: This requires the use of a C++ standard of at least C++17.