模板在元组中循环
template looping through tuple
我正在使用可变模板,目前正在尝试为元组实现operator<<
。
我尝试了以下代码,但它没有编译(GCC 4.9,-std=c++11)。
template<int I, typename ... Tlist>
void print(ostream& s, tuple<Tlist...>& t)
{
s << get<I>(t) << ", ";
if(I < sizeof...(Tlist)){
print<I+1>(s,t);
}
}
template<typename ... Tlist>
ostream& operator<<(ostream& s, tuple<Tlist...> t)
{
print<0>(s,t);
return s;
}
错误消息非常神秘和长,但它基本上表明get没有匹配的函数调用。有人能解释一下为什么吗?谢谢
编辑:这是我使用的模板实例化
auto t = make_tuple(5,6,true,"aaa");
cout << t << endl;
if (blah) {
块中的代码}
已编译,并且即使条件blah
为false,代码也必须有效。
template<bool b>
using bool_t = std::integral_constant<bool, b>;
template<int I, typename ... Tlist>
void print(std::ostream& s, std::tuple<Tlist...> const& t, std::false_type) {
// no more printing
}
template<int I, typename ... Tlist>
void print(std::ostream& s, std::tuple<Tlist...> const& t, std::true_type) {
s << std::get<I>(t) << ", ";
print<I+1>(s, t, bool_t<((I+1) < sizeof...(Tlist))>{});
}
template<typename ... Tlist>
std::ostream& operator<<(std::ostream& s, std::tuple<Tlist...> const& t)
{
print<0>(s,t, bool_t<(0 < sizeof...(Tlist))>{});
return s;
}
应该起作用。在这里,我们使用标记调度来控制我们递归调用的重载:如果I
是元组的有效索引,则第三个参数为true_type
,如果不是,则为false_type
。我们这样做而不是if
语句。我们总是递归,但当我们到达元组的末尾时,我们递归到终止重载中。
实例
顺便说一句,为std
中定义的两个类型重载<<
是否符合标准是不明确的:这取决于std::tuple<int>
是否是"用户定义的类型",即标准没有定义的子句。
最重要的是,在类型的命名空间中重载该类型的运算符被认为是最佳实践,因此可以通过ADL找到它。但是,根据标准,在std
中重载<<
是非法的(不能向std
中注入新的重载)。在某些情况下,如果发现错误的过载,或者没有发现过载,结果可能会有点令人惊讶。
您必须使用专业化或SFINAE作为分支,即使它没有被使用也会生成实例化:
template<int I, typename ... Tlist>
void print(ostream& s, tuple<Tlist...>& t)
{
s << get<I>(t) << ", ";
if(I < sizeof...(Tlist)){
print<I+1>(s,t); // Generated even if I >= sizeof...(Tlist)
}
}
因此,如果get<sizeof...(Tlist)>
不尽快产生错误,那么您将拥有print
的无限实例化。
您可以使用在不递归的情况下编写它
template<std::size_t ... Is, typename Tuple>
void print_helper(std::ostream& s, const Tuple& t, std::index_sequence<Is...>)
{
int dummy[] = { 0, ((s << std::get<Is>(t) << ", "), 0)...};
(void) dummy; // remove warning for unused var
}
template<typename Tuple>
void print(std::ostream& s, const Tuple& t)
{
print_helper(s, t, std::make_index_sequence<std::tuple_size<Tuple>::value>());
}
实例
相关文章:
- C++:TypeDef使用元组
- Pybind11:将元组列表从Python传递到C++
- 重载元组索引运算符-C++
- 在C++中,如何通过几种类型从元组中选择多个元素
- 将fold表达式与std::一起用于两个元组
- std::ranges::elements_view,用于自定义类似元组的数据
- 将元组的向量转换/构造为堆
- 专用于 std 元组的模板,而无需用户执行remove_cvref
- 将元组的向量构造成堆
- 元组由 Swig 生成的 Python 包装器返回,用于C++向量
- 将元组类型扩展为可变参数模板?
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 类内部和外部静态 constexpr 元组之间的差异
- 可变参数模板与使用元组在参数中添加不同的数据对
- 使用提升蟒蛇元组,如何循环元组项目?
- 为什么我在循环提升时得到意外的索引::hana::元组
- 在循环中组合元组
- 复制地图<双精度,元组<双精度,双精度>>映射<双精度,双精度>没有循环?
- 模板在元组中循环
- 循环遍历类模板中的元组,插入vector元素