【问题标题】:Overloading output << operator for a class to print the tuple inside it [duplicate]为类重载输出<<运算符以打印其中的元组[重复]
【发布时间】:2016-09-12 16:51:43
【问题描述】:

所以如果我有这样的事情

template<typename... Args >
class tuple_class
{
  public:
  std::tuple<Args...> tup;

/*I left out the other functions */
};

我想重载运算符

例如

auto a = tuple_class(1, 2 ,3);
std::cout << a << endl;

希望打印 '123'

我看过其他元组打印机的例子,但我无法将它应用到我的课堂上而不会遇到很多麻烦

我想我应该从这样的成员函数开始

  template<typename... Args>
  friend std::ostream& operator<<(std::ostream& os, const my_tuple<Args...> &m);

然后是类外的实际函数

template<typename... Args>
std::ostream& operator<<(std::ostream& os, const my_tuple<Args...> &m)
{
   os << "SOMETHING" << std::endl;
   return os;
}

当我在课堂上调用

任何帮助将不胜感激

【问题讨论】:

  • 您需要通过部分特化递归展开可变参数模板。见this question。

标签: c++ operator-overloading tuples iostream


【解决方案1】:

为了构建解决方案,我使用了来自cppreference 的元组打印代码,这里提到了this。其余的代码是粘合在一起的粘合剂。 Here我放了工作样本。

#include <tuple>
#include <iostream>
#include <string>

// tuple printer
template<class Tuple, std::size_t N>
struct TuplePrinter {
    static std::ostream& print(std::ostream& os, const Tuple& t)
    {
        TuplePrinter<Tuple, N - 1>::print(os, t);
        os << ", " << std::get<N - 1>(t);
        return os;
    }
};

template<class Tuple>
struct TuplePrinter<Tuple, 1> {
    static std::ostream& print(std::ostream& os, const Tuple& t)
    {
        os << std::get<0>(t);
        return os;
    }
};

template<class... Args>
std::ostream& print(std::ostream& os, const std::tuple<Args...>& t)
{
    os << "(";
    TuplePrinter<decltype(t), sizeof...(Args)>::print(os, t);
    os << ")\n";
    return os;
}


// class to keep tuple inside
template<typename... Args>
class tuple_class {
    template<typename... Args2>
    friend std::ostream& operator<<(std::ostream& os, const tuple_class<Args2...> &m);

    std::tuple<Args...> tup;
public:
    tuple_class(Args&&... args) : tup(std::forward<Args>(args)...) {

    }
};

// usage of the printer
template<typename... Args>
std::ostream& operator<<(std::ostream& os, const tuple_class<Args...> &m) {
    print(os, m.tup);
    return os;
}



int main() {
    tuple_class<int,float,std::string> tc( 1,3.0f,"string" );
    std::cout << tc;
    return 0;
}

【讨论】:

  • 感谢您的回复,当我尝试此操作时出现 2 个错误:错误:无法将 'std::ostream {aka std::basic_ostream}' lvalue 绑定到 'std::basic_ostream&&' os (t);和错误:不匹配‘operator}’和‘std::__tuple_element_t
  • 您能否提供您的编译器的确切版本以及编译器标记您是否可以使用?
  • 我修复了它与我构建元组的方式有关。谢谢!
【解决方案2】:

如果您可以不用标准元组,我提出以下简单(我希望如此)的解决方案。

#include <iostream>

template <typename ... Args >
class my_tuple;

template <typename A0, typename ... Args >
class my_tuple<A0, Args...>
 {
   private:

      A0                 elem;
      my_tuple<Args...>  next;

   public:

      my_tuple (const A0 & a0, const Args & ... args)
         : elem { a0 }, next { args ... }
       { }

      /*I left out the other functions */

      friend std::ostream& operator<< (std::ostream & os,
                                       const my_tuple<A0, Args...> & m)
       { return os << m.elem << m.next; }
 };

template <>
class my_tuple<>
 { 
   public:

      friend std::ostream& operator<< (std::ostream & os,
                                       const my_tuple<> &)
       { return os; }
 };

int main ()
 {
   my_tuple<int, float, long>  mt1 { 12, 23.4, 45L };
   my_tuple<int, int, int>     mt2 { 1, 2, 3 };

   std::cout << "my tuple 1 [" << mt1 << ']' << std::endl;
   std::cout << "my tuple 2 [" << mt2 << ']' << std::endl;

   return 0;
 }

【讨论】:

    猜你喜欢
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    相关资源
    最近更新 更多