【发布时间】: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<> StaticLexContext<0> { /* doesn't derive from LexContext, no initCapture method */ }。)您需要帮助编译器并写this->initCapture()说“initCapture 方法来自我的基类,相信我。” -
Raymond Chen - 完美!那解决了它。我想知道为什么我以前从未遇到过这个问题?那好吧。非常感谢!
-
有可能你只是很幸运,以前从未从模板类型派生过,或者至少如果你这样做了,你并没有跌入这个黑暗的角落。过去的编译器也更能容忍这个错误,但近年来他们变得更加严格,以提高标准一致性。
-
编译器可能更宽容。多年来,我从 C++ 休假,用 C# 进行 .NET 开发,与此同时,C++ 发展了很多!我对 C++20 感到很兴奋。协程!耶!我喜欢 C# 的这一点(除了它称它们为迭代器)
标签: c++11 inheritance protected