【问题标题】:C++ protected function not visible from derived classC++ 受保护的函数在派生类中不可见
【发布时间】:2021-03-24 09:15:53
【问题描述】:

我正在尝试调用在 LexContext 中声明为纯虚拟的 initCapture()。我试图通过覆盖它的 StaticLexContext 在 ArduinoLexContext 中间接调用它。

我明白了

LexContext.hpp:316:25: error: there are no arguments to 'initCapture' that depend on a template parameter, so a declaration of 'initCapture' must be available [-fpermissive]

这是代码。我省略了大部分 LexContext,因为它在这里不相关。我整个上午都在做这件事,我知道答案就在我眼前,但我需要另一双眼睛。

提前致谢。

#include <cstdint>
#include <ctype.h>
#include <stdlib.h>
namespace lex {
  // represents a cursor and capture buffer over an input source
  class LexContext {
      int16_t _current;
      unsigned long int _line;
      unsigned long int _column;
      unsigned long long _position;
    protected:
      // reads a character from the underlying device
      // read() should return EndOfInput if no more data is available,
      // and Closed if the underlying source has been closed, where
      // applicable
      virtual int16_t read()=0;
      // called to initialize the capture buffer
      virtual void initCapture()=0;
    public:
      ...

  };
// represents a LexContext with a fixed size buffer
  template<const size_t S> class StaticLexContext : virtual public LexContext {
    char _capture[S];
    size_t _captureCount;
    protected:
      // initializes the capture buffer
      void initCapture() override {
        *_capture=0;
        _captureCount=0;

      }
    public:
      StaticLexContext() {
            
      }
      // the capacity of the capture buffer (not including the trailing NULL)
      size_t captureCapacity() override { return S-1; }
      // the count of characters in the capture buffer
      size_t captureCount() const override {return _captureCount;}
      // returns a pointer to the capture buffer
      char* captureBuffer() override {return _capture;}
      // clears the capture buffer
      void clearCapture() override {
        _captureCount = 0;
        *_capture=0;
      }
      // captures the character under the cursor if any
      // returns true if a character was captured.
      bool capture() override {
        if (Closed!=current() && EndOfInput != current() && BeforeInput != current() && (S - 1) > _captureCount)
        {
          _capture[_captureCount++] = (uint8_t)current();
          _capture[_captureCount] = 0;
          return true;
        }
        return false;
      }

  };
#ifdef ARDUINO
  // represents a fixed length LexContext for the Arduino built on the Arduino SDK's Stream class
  template<const size_t S> class ArduinoLexContext : public StaticLexContext<S> { 
        Stream* _pstream;
    protected:
        // reads a character from the stream
        int16_t read() override {
            if(!_pstream)
              return LexContext::Closed;
            return _pstream->read();
        }
    public:
      ArduinoLexContext() {
            
      }
        // initializes the lexcontext with a stream
        bool begin(Stream& stream) {
            _pstream = &stream;
            initCapture(); // compile error!
            return true;
        }
    };
#endif
}

【问题讨论】:

  • 问题不在于受保护。问题是 ArduinoLexContext 派生自模板类。编译器看到initCapture(); 并说:“这是从基类派生的成员函数吗?还是全局函数?我假设它是一个全局函数。错误:没有名为initCapture 的全局函数。” (可能有专门的 template&lt;&gt; StaticLexContext&lt;0&gt; { /* doesn't derive from LexContext, no initCapture method */ }。)您需要帮助编译器并写 this-&gt;initCapture() 说“initCapture 方法来自我的基类,相信我。”
  • Raymond Chen - 完美!那解决了它。我想知道为什么我以前从未遇到过这个问题?那好吧。非常感谢!
  • 有可能你只是很幸运,以前从未从模板类型派生过,或者至少如果你这样做了,你并没有跌入这个黑暗的角落。过去的编译器也更能容忍这个错误,但近年来他们变得更加严格,以提高标准一致性。
  • 编译器可能更宽容。多年来,我从 C++ 休假,用 C# 进行 .NET 开发,与此同时,C++ 发展了很多!我对 C++20 感到很兴奋。协程!耶!我喜欢 C# 的这一点(除了它称它们为迭代器)

标签: c++11 inheritance protected


【解决方案1】:

雷蒙德陈在 cmets,伙计们。他是个英雄。

问题不在于受保护。问题是 ArduinoLexContext 派生自一个模板类。编译器看到 初始化捕获();并说,“这是一个从一个派生的成员函数吗? 基类?或者它是一个全局函数?我会假设这是一个 全局函数。错误:没有名为 initCapture 的全局函数。”(有 可能是一个特化模板 StaticLexContext { /* 不是 派生自 LexContext,没有 initCapture 方法 */ }。)您需要帮助 退出编译器并编写 this->initCapture() 来表示“initCapture 方法来自我的基类,相信我。”

– 陈瑞峰

【讨论】:

    猜你喜欢
    • 2012-06-05
    • 2010-09-30
    • 2015-04-21
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    • 2017-09-14
    • 2020-12-24
    相关资源
    最近更新 更多