gpt4 book ai didi

c++ - 内部类的不可见运算符<<重载

转载 作者:行者123 更新时间:2023-11-30 02:44:35 25 4
gpt4 key购买 nike

为什么 main 中的 operator<< 没有为派生类获取重载?

#include <iostream>

struct Base {};

std::ostream& operator<<(std::ostream& os, const Base&) { return os << "Hi\n"; }

template <class T>
struct Container
{
class Derived : Base {
template <class U>
friend std::ostream& operator<<(std::ostream& os, const typename Container<U>::Derived&);
};
};

template <class U>
std::ostream&
operator<<(std::ostream& os, const typename Container<U>::Derived& der)
{
return os << static_cast<const Base&>(der);
}

int main()
{
Container<int>::Derived d;
std::cout << d;
return 0;
}

g++ 说:

/tmp $ g++ test.c
test.c: In function ‘int main()’:
test.c:28: error: ‘Base’ is an inaccessible base of ‘Container<int>::Derived’
/tmp $

编辑:私有(private)继承是有意的。这就是 operator<< 被声明为“ friend ”的原因。

EDIT2:好友声明固定位置;在内部类中。

最佳答案

在你的:

template <class U>
std::ostream&
operator<<(std::ostream& os, const typename Container<U>::Derived& der)

U在第二个参数中是在非推导上下文中(参见§14.8.2.5/5),所以编译器找不到这个函数在 operator<< 上进行运算符重载解析在 main .结果,没有实例化这个函数在重载集中,和重载决议(总是忽略访问问题)选择非模板 operator<<服用Base const& .然后访问控制导致错误你看到了。

有几种解决方案。可能最简单的方法是声明operator<<对于 Derived作为模板,但要在 Derived 中将其实现为内联好友:

friend std::ostream& operator<<( std::ostream& dest, Derived const& obj )
{
return os << static_cast<Base const&>( obj );
}

这是如何工作的有点棘手。你要声明的 friend 不是模板;有一个单独的非模板函数对于 Container 的每个实例.如果不是内联,你必须提供一个单独的、非模板化的实现对于每种类型。但是因为它是内联的,所以编译器提供了它为你。而且虽然没有注入(inject)函数的名称在周围环境中,它会被 ADL 发现。

当然,因为这个 operator<<不是模板,有找到它不涉及论证推导。

关于c++ - 内部类的不可见运算符<<重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25167248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com