【问题标题】:Overload operator<< for nested class template嵌套类模板的重载运算符<<
【发布时间】:2013-09-20 08:14:20
【问题描述】:

我有以下设置:

template< class T >
struct Foo {

  struct Bar {
    Bar ( const T &t ) : otherT_( t ) {}

    T otherT_;
  };

  Foo ( const T &t ) : myT_( t ) {}

  T myT_;
};

现在,我想让 Foo&lt; T &gt;::Bar 的实例可流式传输到 std::cout 和朋友。我试过这个:

template< class T >
std::ostream& operator<< ( std::ostream &os, 
                           const typename Foo< T >::Bar &bar ) {
  os << "<bar: " << bar.otherT_ << ">";
  return os;
}

但以下代码无法编译:

  Foo< int > foo( 5 );
  Foo< int >::Bar bar( 7 );

  std::cout << bar << std::endl;

我猜编译器无法推断出T 的类型。有没有办法使嵌套类的此类实例与operator&lt;&lt; 一起表现良好?

谢谢!

【问题讨论】:

  • 复制/粘贴this answer?
  • @KerrekSB 所以答案是不可能简单地写成std::cout &lt;&lt; bar ?或者我可以明确链接答案中提到的一对一映射吗?
  • @KerrekSB 我不确定我是否遵循引用的答案。他的错误的原因很简单:Foo&lt;T&gt;::Bar 中的T 是一个非推导上下文,参见§14.8.2.5/5。正如其他人指出的那样,使函数成为朋友是可行的(因为生成的函数不是模板,所以不需要类型推导)。
  • @JamesKanze:“非推断上下文”是这两个问题的共同原因。考虑到给定X,你可以为T 解决Foo&lt;T&gt;::Bar = X 始终是个问题。
  • @KerrekSB 这不是你能不能解决问题的问题,而是标准规定你不能尝试的事实。 (事实上​​,这个问题是可以解决的,但标准委员会认为当前的编译器技术很复杂。)

标签: c++ templates operator-overloading friend nested-class


【解决方案1】:

是的,简单的方法是将operator&lt;&lt; 放入Bar

struct Bar {
  Bar ( const T &t ) : otherT_( t ) {}

  T otherT_;

  friend std::ostream& operator<< ( std::ostream &os, const Bar &bar ) 
  {
    os << "<bar: " << bar.otherT_ << ">";
    return os;
  }
};

我在挖另一边……

【讨论】:

  • :) 仍在尝试另一种方式 :)
  • 我认为模板别名可能有助于推断,但 this answer 让我直截了当
【解决方案2】:

解决方法 - 将 operator&lt;&lt; 定义为 Bar 定义中的朋友:

template< class T >
struct Foo {

  struct Bar {
    Bar ( const T &t ) : otherT_( t ) {}

    T otherT_;

    friend std::ostream& operator<< ( std::ostream &os, const Bar &bar )
    {
      os << "<bar: " << bar.otherT_ << ">";
      return os;
    }

  };

  Foo ( const T &t ) : myT_( t ) {}

  T myT_;
};

正如 KerrekSB 在 cmets 中所说,您的方法的问题是无法推断出 T。 Foo&lt;T&gt;::Bar 可能有无限多个 T,每个都可能导致不同的类型。

【讨论】:

    【解决方案3】:

    编译器无法推断 T,但是,当您将其设为朋友时,它会通过 ADL 找到它。

    我已将代码修改为以下内容:

    #include <iostream>
    using namespace std;
    
    template< class T >
    struct Foo {
    
    struct Bar {
    Bar ( const T &t ) : otherT_( t ) {}
    
    T otherT_;
    friend std::ostream& operator << (std::ostream& os, const Bar &bar )
    { return os; }
    };
    
    Foo ( const T &t ) : myT_( t ) {}
    
    
    T myT_;
    };
    
    int main() {
    Foo< int > foo( 5 );
    Foo< int >::Bar bar( 7 );
    
    std::cout << bar << std::endl;
    return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-28
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多