C++ 我能得到“吗?”;“反对者名单”;std::tuple的行为?
我想递归地定义一个函数来设置std::tuple的所有元素。如果它是boost::tuple,我只需查看并复制以下示例:C++ 我能得到“吗?”;“反对者名单”;std::tuple的行为?,c++,c++11,stdtuple,C++,C++11,Stdtuple,我想递归地定义一个函数来设置std::tuple的所有元素。如果它是boost::tuple,我只需查看并复制以下示例: inline void set_to_zero(const null_type&) {}; template <class H, class T> inline void set_to_zero(cons<H, T>& x) { x.get_head() = 0; set_to_zero(x.get_tail()); } inlin
inline void set_to_zero(const null_type&) {};
template <class H, class T>
inline void set_to_zero(cons<H, T>& x) { x.get_head() = 0; set_to_zero(x.get_tail()); }
inline void set_to_zero(const null_type&){};
模板
内联void set_to_zero(cons&x){x.get_head()=0;set_to_zero(x.get_tail());}
到目前为止,对于std::tuple,我找不到任何类似的简单方法。附近有什么吗
更新:好的,我需要进一步充实这个问题
template<typename T>
struct simple_setter
{
void set(T &target); // somebody else's stuff, defined elsewhere
};
template<typename Tuple> class foo;
template<>
struct foo<boost::tuple<>>
{
foo() {}
void set(boost::tuple<> &target) {}
};
template<typename E, typename... Es>
struct foo<boost::tuple<E, Es...>>
{
explicit foo(const simple_setter<E> &head_setter, const simple_setter<Es> & ... other_setters) :
_head(head_setter),
_tail(other_setters)
{}
void set(boost::tuple<E, Es...> &target) {
_head.set(target.get_head()),
_tail.set(target.get_tail())
}
// more methods to do other things
const simple_setter<E> &_head;
const foo<boost::tuple<Es ...>> _tail;
};
模板
结构简单设置器
{
void set(T&target);//其他人的东西,在别处定义
};
模板类foo;
模板
结构foo
{
foo(){}
空集(boost::tuple&target){}
};
模板
结构foo
{
显式foo(const-simple\u-setter和head\u-setter、const-simple\u-setter和其他\u-setter):
_头部(头部设置器),
_尾部(其他设置器)
{}
无效集(boost::tuple和target){
_head.set(target.get_head()),
_tail.set(target.get_tail())
}
//更多的方法做其他事情
常量简单设置器和头;
康斯特富尾;
};
我正在编写封装一个元组的foo类,以完成一系列的工作,其中一项就是设置所有元素。我本来希望保留foo的这种递归定义,但是要从boost::tuples切换到std::tuples。递归可以通过这种方式实现
template < typename _Tuple >
inline void set_to_zero(_Tuple& tuple, std::integral_constant<size_t, 0>)
{
}
template < typename _Tuple, size_t N >
inline void set_to_zero(_Tuple& tuple, std::integral_constant<size_t, N>)
{
set_to_zero(tuple, std::integral_constant<size_t, N - 1>());
// action(std::get<N - 1>(tuple));
}
template < typename _Tuple >
inline void set_to_zero(_Tuple& tuple)
{
set_to_zero(tuple, std::integral_constant<size_t, std::tuple_size<_Tuple>::value>());
}
template
内联void设置为零(_Tuple&Tuple,std::integral_常量)
{
}
模板
内联void设置为零(_Tuple&Tuple,std::integral_常量)
{
将_设置为_零(元组,std::integral_常量());
//动作(std::get(tuple));
}
模板
内联void设置为0(_Tuple&Tuple)
{
将_设置为_零(元组,std::integral_常量());
}
或者更一般的形式
template < typename _Tuple, typename _Func >
inline void for_each(_Tuple& tuple, _Func func_, std::integral_constant<size_t, 0>)
{
}
template < typename _Tuple, typename _Func, size_t N >
inline void for_each(_Tuple& tuple, _Func func_, std::integral_constant<size_t, N>)
{
for_each(tuple, func_, std::integral_constant<size_t, N - 1>());
func_(std::get<N - 1>(tuple));
}
template < typename _Tuple, typename _Functor >
inline void for_each(_Tuple& tuple, _Functor func_)
{
for_each(tuple, func_, std::integral_constant<size_t, std::tuple_size<_Tuple>::value>());
}
模板
每个的内联void(_Tuple&Tuple,_funcfunc,std::integral_常量)
{
}
模板
每个的内联void(_Tuple&Tuple,_funcfunc,std::integral_常量)
{
对于每个(元组、func、std::integral_常量());
func(std::get(tuple));
}
模板
每个函数的内联void(_Tuple&Tuple,_functorfunc)
{
对于每个(元组、func、std::integral_常量());
}
广义形式的使用示例
struct DoSomething
{
void operator()(int a) {} // overload for int
void operator()(double a) {} // overload for double
};
std::tuple<int, double> tuple_;
for_each(tuple_, DoSomething());
struct DoSomething
{
void运算符()(int a){}//int的重载
void运算符()(双精度a){}//双精度的重载
};
std::tuple-tuple;
对于每个(元组,DoSomething());
为什么是递归的?为什么不一次将所有元素设置为零呢?我在寻找问题的最简单形式,但我发现我简化得太多了。在这里,我将对表示进行一种不太剧烈的简化,但同时,您对一次设置所有元素有什么想法?template void set_to_zero(std::tuple&t){t=std::tuple{};}
是一种将整个元组设置为值初始化状态的简单方法。我想您可以使它更通用:template void将_设置为_zero(T&T){T=T{};}
并且它会将任何内容置零。不过,对更一般的问题可能没有什么帮助。boost::tuple
实际上是递归实现的。实际上,我认为std::tuple
仍然需要递归实现,但是规范没有定义对.tail()
@JanHudec:Nope的访问,而且递归实现实际上更复杂,效率更低。谢谢,但我认为您的“更一般的形式”在一个方面不那么笼统。在第一种形式中,您称为“action”,它可以为不同类型的元素选择不同的重载;而在你的第二种形式中,同样的“func_”到处都被调用。因此,您可以选择第一种形式,以便提取“action”的重载。但是如果你想要重载函数的相同模式,另一个_动作,还有另一个_动作,你必须一次又一次地写出递归。。。或者有什么方法可以让你在这里吃蛋糕?函数不需要函子。它也可以是一个定义运算符()的类。请参阅答案末尾的用法示例