首页 > 解决方案 > 基类中的函数名解析

问题描述

考虑以下代码片段,

#include <memory>

template <typename Derived>
class Base
{
public:
    int foo()
    {
        return static_cast<Derived*>(this)->bar(); // I expected a compilation error here
    }

private:
    int bar()
    {
        return 1;
    }
};

class Derived : public Base<Derived> {};

int baz()
{
    return std::unique_ptr<Derived>()->foo();
}

据我了解,模板类Base将该函数声明bar为私有,因此即使是Derived类也不可见,更不用说任何Derived对象的用户了。

在模板类Base的公共函数foo中,我尝试bar通过一个Derived对象来访问一个不存在的函数。我预计编译器无法找到该函数bar

Q. 编译器如何通过对象的使用找到模板类的私有bar函数?BaseDerived https://godbolt.org/z/jVxW-k

Derived现在考虑对其中类不再为空的代码段进行轻微变化。

class Derived : public Base<Derived>
{
private:
    int bar()
    {
        return 1;
    }
};

在这里,预期的输出是编译器错误的消息,

<source>: In instantiation of 'int Base<Derived>::foo() [with Derived = Derived]':

<source>:30:44:   required from here

<source>:9:49: error: 'int Derived::bar()' is private within this context

    9 |         return static_cast<Derived*>(this)->bar();

      |                                                 ^

<source>:22:9: note: declared private here

   22 |     int bar()

      |         ^~~

Compiler returned: 1

问:为什么编译器bar现在无法找到私有函数?有什么方法可以强制派生实现来实现该功能bar https://godbolt.org/z/PrkNo6

使用的编译器:g++ 9.2。使用的编译器标志:-std=c++17 -O3 -Wall -Werror.

提前致谢!!!

标签: c++

解决方案


Q. 编译器如何通过Derived对象找到Base模板类的私有bar函数?

为了

return static_cast<Derived*>(this)->bar();

Derived没有bar
查看基类发现Base::bar

我们在Base范围内,所以我们可以访问Base::bar(即使应用于其他类型)

Q. 为什么编译器现在找不到私有函数栏?有什么方法可以强制派生实现来实现功能栏?

现在,Derived有一个bar, 停止查找。

Derived::bar在 的范围内是私有Base的(即使应用于Derived实例)。


推荐阅读