处理"returning"多个值的函数的模板
Templates handling functions "returning" more than one value
有时您希望一个函数返回多个值。一种非常常见的方法在C++中实现这样的行为是通过非常量引用传递您的值,并且在函数中分配给它们:
void foo(int & a, int & b)
{
a = 1; b = 2;
}
您将使用:
int a, b;
foo(a, b);
// do something with a and b
现在我有一个接受这样一个函数的函子,并希望转发将参数设置到返回结果的另一个函数中:
template <typename F, typename G>
struct calc;
template <
typename R, typename ... FArgs,
typename G
>
struct calc<R (FArgs...), G>
{
using f_type = R (*)(FArgs...);
using g_type = G *;
R operator()(f_type f, g_type g) const
{
// I would need to declare each type in FArgs
// dummy:
Args ... args;
// now use the multiple value returning function
g(args...);
// and pass the arguments on
return f(args...);
}
};
这种方法是否有意义,或者我应该使用基于元组的元组方法?这里有比基于元组的方法更聪明的方法吗?
您可以使用编译时索引:
template< std::size_t... Ns >
struct indices
{
typedef indices< Ns..., sizeof...( Ns ) > next;
};
template< std::size_t N >
struct make_indices
{
typedef typename make_indices< N - 1 >::type::next type;
};
template<>
struct make_indices< 0 >
{
typedef indices<> type;
};
template< typename F, typename G >
struct calc;
template<
typename R, typename ... FArgs,
typename G
>
struct calc< R (FArgs...), G >
{
using f_type = R (*)(FArgs...);
using g_type = G *;
private:
template< std::size_t... Ns >
R impl(f_type f, g_type g, indices< Ns... > ) const
{
std::tuple< FArgs ... > args;
g( std::get< Ns >( args )... );
// alternatively, if g() returns the tuple use:
// auto args = g();
return f( std::get< Ns >( args )... );
}
public:
R operator()(f_type f, g_type g) const
{
return impl( f, g, typename make_indices< sizeof...( FArgs ) >::type() );
}
};
当接受我们正在更改f
和g
的签名以使用std::tuple
的事实时,这个问题的答案变得微不足道:
template <typename F, typename G> struct calc;
template <typename R, typename ... Args>
struct calc<R (std::tuple<Args...> const &), std::tuple<Args...> ()>
{
using f_type = R (*)(std::tuple<Args...> const &);
using g_type = std::tuple<Args...> (*)();
R operator()(f_type f, g_type g) const
{
return f(g());
}
};
下面是一个简单的示例:
int sum(std::tuple<int, int> const & t) { return std::get<0>(t) + std::get<1>(t); }
std::tuple<int, int> gen() { return std::make_tuple<int, int>(1, 2); }
auto x = calc<decltype(sum), decltype(gen)>()(&sum, &gen);
但是,此解决方案的局限性很明显:您必须编写自己的函数。使用这种方法不可能使用类似std::pow
的东西作为f
。
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 为什么 decltype 在 "auto returning" 函数中是必需的?
- 从 std::function 继承构造函数时"function returning a function"
- 循环函数给出"return’ with a value, in function returning void"误差
- 处理"returning"多个值的函数的模板