gpt4 book ai didi

c++ - 为什么编译器在使用 CRTP 时看不到基类的方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:19:09 24 4
gpt4 key购买 nike

我有以下代码:

struct Iface
{
virtual int Read() = 0;

int Read(int x) {
return Read() + x;
}
};

template <typename Impl>
struct Crtp : public Iface
{
virtual int Read() {
return static_cast<Impl&>(*this).ReadImpl();
}
//using Iface::Read;
};

struct IfaceImpl : public Crtp<IfaceImpl>
{
int ReadImpl() {
return 42;
}
};

int main()
{
IfaceImpl impl;
impl.Read(24); // compilation error

Iface& iface = impl;
iface.Read(24); // always compiles successfully
}

msvc、gcc 和 clang 都拒绝此代码,它们找不到方法 Read(int x)

但是,如果我在 Crtp 中取消注释 using Iface::Read,我的代码将成功编译。

请注意,如果我引用 Iface,我可以调用 Read(int x)

为什么会这样?

最佳答案

Why does this happen?

您的问题与 CRTP 无关。这是在正常的继承场景中可能发生的名称隐藏问题。

调用impl.Read(24);时,IfaceImpl类作用域内找不到成员函数名Read >。然后将检查基类 Crtp 的范围,并在那里找到名称 Read。然后名称查找停止,因此进一步基类 Iface 中的 int Read(int x) 不会被考虑用于重载解析,即使它在这里更合适。

通过 using Iface::Read;,您将名称 Read 引入到 Crtp 的类作用域中。然后可以通过重载解析正确地找到和选择它。

如果您通过 Iface 引用调用它,名称查找将正常工作。

或者您可以通过 impl.Iface::Read(24); 显式地(丑陋地)调用它。

参见 Unqualified name lookup :

... name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

关于c++ - 为什么编译器在使用 CRTP 时看不到基类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37696703/

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