我有一个Foo
定义内部 struct 的模板结构Bar
。
现在,我想重载operator <<
此内部 struct 的流Bar
,但编译器似乎忽略了我的重载实现:
错误:与 'operator<<' 不匹配(操作数类型为 'std::ostream' {aka 'std::basic_ostream<char>'} 和 'Foo<3>::Bar')
我的代码如下:
#include <iostream>
//////////////////////////////////////////////////////////////////////////////////////////
template<int N>
struct Foo
{
struct Bar {};
};
//////////////////////////////////////////////////////////////////////////////////////////
template<int N>
std::ostream& operator<< (std::ostream& os, const typename Foo<N>::Bar& x)
{
return os;
}
//////////////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
Foo<3>::Bar x;
std::cout << x << std::endl;
}
我看不到(也许是明显的)错误。
问题是否可以重载属于模板类的内部结构的运算符?
是的,像这样:
在您的代码中,
operator<<
实际上并没有错误。这是不可能推断出来N
的Foo<N>::Bar
。您只能通过N
显式调用它:现场演示。
原因是这
Foo<N>::Bar
是一个非推导的上下文。请参阅什么是非推导上下文?更多细节。简而言之,这不起作用的原因是Foo<N>::Bar
和之间不存在 1:1 关系N
。考虑您添加一个专业:现在
Foo<42>::Bar
和Foo<3>::Bar
指的是完全相同的类型。这和这个
必须推断出不同的值,
N
但在两个示例中x
都是完全相同的类型。你的意思是这样的吗?使用模板类,通常更容易在模板中声明友元重载(此处演示: https: //onlinegdb.com/NqTLD6_tU)