【问题标题】:Recursive printing of tuple in C++C++中元组的递归打印
【发布时间】:2014-06-21 14:31:52
【问题描述】:

有几个关于如何打印tuple 的建议。下面的 sn-p 复制了来自overloading operator << for std::tuple - possible simplications? 的 Kenny 的答案。

#include <iostream>
#include <tuple>
#include <type_traits>

// template <typename... T>
// std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& tup);

template <size_t n, typename... T>
typename std::enable_if<(n >= sizeof...(T))>::type
print_tuple(std::ostream&, const std::tuple<T...>&)
{}

template <size_t n, typename... T>
typename std::enable_if<(n < sizeof...(T))>::type
print_tuple(std::ostream& os, const std::tuple<T...>& tup)
{
  if (n != 0)
    os << ", ";
  os << std::get<n>(tup);
  print_tuple<n+1>(os, tup);
}

template <typename... T>
std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& tup)
{
  os << "[";
  print_tuple<0>(os, tup);
  return os << "]";
}

int
main()
{
  auto t = std::make_tuple(1, std::make_tuple(2, 3));
    std::cout << t << std::endl;
}

我的问题是它不能与带有元组的元组的 clang (3.5) 一起正常工作(不过 gcc 4.9 很高兴):

clang++-mp-3.5 -std=c++11 print.cc 
print.cc:19:10: error: call to function 'operator<<' that is neither visible in the
      template definition nor found by argument-dependent lookup
      os << std::get<n>(tup);
         ^
print.cc:20:7: note: in instantiation of function template specialization
      'print_tuple<1, int, std::__1::tuple<int, int> >' requested here
      print_tuple<n+1>(os, tup);
      ^
print.cc:27:7: note: in instantiation of function template specialization
      'print_tuple<0, int, std::__1::tuple<int, int> >' requested here
      print_tuple<0>(os, tup);
      ^
print.cc:35:19: note: in instantiation of function template specialization
      'operator<<<int, std::__1::tuple<int, int> >' requested here
        std::cout << t << std::endl;
                  ^
print.cc:24:19: note: 'operator<<' should be declared prior to the call site
    std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& tup)
              ^

如果我取消注释元组上operator&lt;&lt; 的前向声明,它会起作用。但是它不能很好地适合您不强制为元组定义 operator&lt;&lt; 的框架,而是让用户选择将其绑定到 print_tuple:她必须在 之前转发声明函数 包括定义print_tuple 的标头。

我不太明白这里发生了什么:在模板中,clang 似乎拒绝使用在模板定义点之后定义但之前定义的函数 实例化点。我会认为重要的是实例化的点。

反过来,为什么 GCC 接受?编译器之一错了吗?让用户选择定义这个 operator&lt;&lt; 并让它以递归方式正常工作的最佳方式是什么?

谢谢。

【问题讨论】:

标签: gcc c++11 clang tuples variadic-templates


【解决方案1】:

您可以在此处阅读有关 clang 未编译它的原因:http://clang.llvm.org/compatibility.html#dep_lookup。看来clang的行为是符合标准的。

要修复它,您可以在namespace std 中定义operator&lt;&lt; 以使依赖于参数的查找正常工作。 实际上这可能是未定义的行为,因为它不符合添加的要求东西到std。

【讨论】:

  • 无赖,当然问题出在namespace :( 我怎么会忘记这么明显的东西。谢谢!
猜你喜欢
  • 2022-01-02
  • 1970-01-01
  • 2019-04-03
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
  • 2023-02-18
  • 2013-12-12
  • 2016-05-07
相关资源
最近更新 更多