提问人:edrezen 提问时间:11/15/2023 最后编辑:Remy Lebeauedrezen 更新时间:11/15/2023 访问量:149
重载模板结构内结构的运算符 [duplicate]
Overload an operator of a struct inside a template struct [duplicate]
问:
我有一个模板结构,它定义了一个内部结构。Foo
Bar
现在,我想重载这个内部结构的流,但编译器似乎忽略了我的重载实现:operator <<
Bar
错误:与“operator<<”不匹配(操作数类型为“std::ostream”{又名“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;
}
我看不到(也许很明显的)错误。
问题是否可以重载属于模板类的内部结构的运算符?
答:
2赞
Pepijn Kramer
11/15/2023
#1
你是这个意思吗? 使用模板类,通常更容易在模板中声明友元重载(此处的演示:https://onlinegdb.com/NqTLD6_tU)
#include <iostream>
template<int N>
struct Foo
{
struct Bar
{
int x{N};
};
// friend if you need access to a private member
friend std::ostream& operator<<(std::ostream& os, const Foo<N>::Bar& bar)
{
os << bar.x;
return os;
}
private:
Bar b;
};
int main (int argc, char** argv)
{
Foo<3>::Bar x;
std::cout << x << "\n";
}
评论
0赞
Jerry Coffin
11/15/2023
请注意,由于它现在位于 的定义中,因此您可以稍微简化运算符的参数声明,将其简化为 ,而不是 。godbolt.org/z/33xno8qMbFoo
const Bar &
const Foo<N>::Bar &
0赞
edrezen
11/15/2023
谢谢你的回答。我很确定我尝试了类似的东西,但还不够相似,无法编译!
5赞
463035818_is_not_an_ai
11/15/2023
#2
是的,像这样:
#include <iostream>
template<int N>
struct Foo
{
struct Bar {
friend std::ostream& operator<<(std::ostream& os,const Bar&) { return os;}
};
};
int main (int argc, char** argv)
{
Foo<3>::Bar x;
std::cout << x << std::endl;
}
在您的代码中,实际上并没有错。它只是不可能从中推断出来。您只能通过显式调用它:operator<<
N
Foo<N>::Bar
N
int main (int argc, char** argv)
{
Foo<3>::Bar x;
operator<<<3>(std::cout,x);
}
现场演示。
原因是这是一个不可推导的上下文。有关更多详细信息,请参阅什么是非推导上下文?简而言之,这不起作用的原因是 和 之间没有 1:1 的关系。考虑添加专业化:Foo<N>::Bar
Foo<N>::Bar
N
template <> struct Foo<42> {
using Bar = Foo<3>::Bar;
};
现在并引用完全相同的类型。这Foo<42>::Bar
Foo<3>::Bar
Foo<3>::Bar x;
std::cout << x;
和这个
Foo<42>::Bar x;
std::cout << x;
必须推断出不同的值,但在两个示例中都是完全相同的类型。N
x
评论
0赞
edrezen
11/15/2023
感谢您的详细回答;我今天在 C++ 中学到了一些新东西,我想我面前有很多这样的日子!
评论