【问题标题】:How to define a template class template friend function which one of its parameters is a dependent name outside the template class body?如何定义模板类模板友元函数,其参数之一是模板类主体之外的依赖名称?
【发布时间】:2021-02-12 09:22:10
【问题描述】:

你好,我有这个程序:

我想创建一个泛型类 Add 作为仿函数,我打算重载流 I/O 运算符以使用它。

问题是我希望流操作符<< >> 也是通用的,因此流参数可以是std::istreamstd::ifstream 等等。这也适用于插入运算符。

我这样做的原因是,如果我写 std::cout << Add<int>{} 会将其打印在屏幕上,如果我这样做:ofstream("data.txt") >> Add<int>{}; 会将其写入文件。

  • 我知道ifstreamistream,但我打算使用其他类型,它们的 I/O 操作符在做其他事情。

      template <typename T>
      class Add
      {
          T operator()(T const& a, T const& b){return a + b;}
    
          template <typename STREAM_IN>
          friend STREAM_IN& operator >> (STREAM_IN& in, Add<T>& a){ in >> a.x; return in;}
    
          template <typename STREAM_OUT>
          friend STREAM_OUT& operator << (STREAM_OUT& out, Add<T> const& a){ out << a.x; return out;}
    
          int x = 89;
      };
    
      //template <typename T>
      //template <typename STREAM_IN>
      //STREAM_IN& operator >> (STREAM_IN& in, Add<T>& a)
      //{
      //    return in >> a.x;
      //}
    
    
      int main()
      {
    
          Add<long> a;
          std::ifstream in("data.txt");
          in >> a;
          std::cout << a << '\n';
          in.close();
          a.x += 7;
          std::ofstream out("data.txt");
          out << a;
    
    
          std::cout << "\ndone!\n";
      }
    
  • 问题:如何在模板类主体之外定义&gt;&gt;&lt;&lt;

【问题讨论】:

    标签: c++ templates friend-function


    【解决方案1】:

    这就是你要找的吗?我只是使用模板为流和 Add 的模板类型定义了两个重载运算符。由于Add 是一个结构而不是一个类,因此您不需要使用友元函数。

    #include <iostream>
    #include <fstream>
    #include <string>
    
    template <typename T>
    class Add
    {
        T operator()(T const& a, T const& b){return a + b;}
    
        template <typename STREAM, typename T2>
        friend STREAM& operator>>(STREAM& stream, Add<T2>& add);
    
        template <typename STREAM, typename T2>
        friend STREAM& operator<<(STREAM& stream, const Add<T2>& add);
    
        int x = 89;
    
    public:
    // in order to make the main function compile (not used by the operators)
        void add7() { x += 7; }
    };
    
    template <typename STREAM, typename T>
    STREAM& operator>>(STREAM& stream, Add<T>& add) {
        stream >> add.x;
        return stream;
    }
    
    template <typename STREAM, typename T>
    STREAM& operator<<(STREAM& stream, const Add<T>& add) {
        stream << add.x;
        return stream;
    }
    
    int main()
    {
    
        Add<long> a;
        std::ifstream in("data.txt");
        in >> a;
        std::cout << a << '\n';
        in.close();
        a.add7();
        std::ofstream out("data.txt");
        out << a;
    
    
        std::cout << "\ndone!\n";
    }
    

    这部分告诉编译器这个类是一个名为operator&gt;&gt;的函数的朋友,它接受任何类型作为第一个参数和一个类And`` of template type T```。

    template <typename STREAM, typename T2>
    friend STREAM& operator>>(STREAM& stream, Add<T2>& add);
    

    而这部分定义了函数的主体。

    template <typename STREAM, typename T>
    STREAM& operator>>(STREAM& stream, Add<T>& add) {
        stream >> add.x;
        return stream;
    }
    

    【讨论】:

    • 它不起作用,因为您没有将运算符声明为类的朋友。我已将其从 struct 编辑为 class
    • 抱歉没看到!我编辑了我的帖子来解决这个问题!
    • 如果你想ping OP,你应该使用@,否则他们可能看不到评论。
    • @Maestro 这能回答你的问题吗?如果是这样,您可以将其标记为已回答以关闭此问题吗?谢谢。 (@cigien 也是 :-))
    猜你喜欢
    • 1970-01-01
    • 2016-10-19
    • 2011-07-30
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 2021-09-26
    • 2015-10-21
    • 2023-03-13
    相关资源
    最近更新 更多