svo*_*ron 4 c++ inheritance types template-meta-programming c++11
让我们假设有N个函数采用不同的输入并返回不同的值:
int h(int);
string g(int);
double f(string);
Run Code Online (Sandbox Code Playgroud)
当然可以这样写:
f(g(h(4)))
Run Code Online (Sandbox Code Playgroud)
现在假设我想将这些函数f,g,h存储到一种容器中,如:
Container c;
c.add(h);
c.add(g);
c.add(f);
Run Code Online (Sandbox Code Playgroud)
给定第一个函数的输入(在f的情况下为int)我希望这些函数以顺序方式执行,每个函数都将前一个函数的输出作为输入.
你认为在C++中有可能吗?可能没有使用dynamic_cast和使用C++ 11
如果Container需要在运行时进行修改,可以使用std::any(或boost::any)来实现:
struct Container
{
std::vector<std::function<std::any(std::any)>> _fns;
template <typename R, typename A>
void add(R(*f)(A))
{
_fns.emplace_back([f](std::any x) -> std::any
{
return {f(std::any_cast<A>(x))};
});
}
template <typename T>
std::any call(T x)
{
// TODO: replace with recursive version
return _fns[2](_fns[1](_fns[0](x)));
}
};
Run Code Online (Sandbox Code Playgroud)
用法:
int h(int x) { return x; }
std::string g(int x) { return std::to_string(x); }
double f(std::string x) { return x.size(); }
int main()
{
Container c;
c.add(h);
c.add(g);
c.add(f);
std::cout << std::any_cast<double>(c.call(5)) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
输出:
1
可能的递归实现:
template <typename T>
std::any call_impl(T x, const std::size_t next)
{
return next == _fns.size() - 1
? _fns[next](x)
: call_impl(_fns[next](x), next + 1);
}
template <typename T>
std::any call(T x)
{
return call_impl(x, 0);
}
Run Code Online (Sandbox Code Playgroud)