C ++模板声明不可见

bie*_*000 6 c++ templates

我有以下代码:

#include <cstddef>
#include <cstdint>

using ReadIteratorType = Buffer::iterator;
using WriteIteratorType = Buffer::iterator;

template <typename TReadIterator, typename TWriteIterator>
class FieldBase
{
public:
    using ReadIterator = TReadIterator;
    using WriteIterator = TWriteIterator;

    virtual void read(ReadIterator& readIterator, std::size_t& len) = 0;
    virtual void write(WriteIterator& writeIterator, std::size_t& len) = 0;
};

template <typename TValue>
class Field : public FieldBase<ReadIteratorType, WriteIteratorType>
{
public:
    using ValueType = TValue;

    virtual const ValueType& getValue() const { return m_value; };
    virtual void setValue(const ValueType& value) { m_value = value;}
    constexpr std::size_t length() { return sizeof(TValue); }

protected:
    ValueType m_value {};
};

template <typename T>
class IntField : public Field<T>
{
public:

    void read(ReadIterator& readIterator, std::size_t& len) override
    {

    }

    void write(WriteIterator& writeIterator, std::size_t& len) override
    {

    }
};
Run Code Online (Sandbox Code Playgroud)

每当我尝试编译此特定代码时,我都不会

错误:未将'ReadIterator'声明为void read(ReadIterator&readIterator,std :: size_t&len)覆盖

错误:尚未声明'WriteIterator'无效write(WriteIterator&writeIterator,std :: size_t&len)覆盖

但是,如果我将IntField类的定义更改为IntField类:public Field或具有某种类型的任何东西,它将正确编译。为什么在当前上下文中IntField不能作为模板?

Ser*_*eyA 6

这是一个众所周知的问题。编译器不知道ReadIterator需要来自模板化的基类,因为它会在模板实例化的第一步中尝试解析名称。您可以在此处找到有关两阶段名称查找的更多信息:http : //blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html

您需要在这里详细说明:

void read(typename Field<T>::ReadIterator& readIterator, std::size_t& len) override
Run Code Online (Sandbox Code Playgroud)

或者,保存一些输入内容:

using base_t = Field<T>;
void read(typename base_t::ReadIterator& readIterator, std::size_t& len) override
Run Code Online (Sandbox Code Playgroud)

顺便提一句,您的代码对我而言没有太多意义。我希望您的IntField 不是模板:

class IntField : public Field<int>
// ...
Run Code Online (Sandbox Code Playgroud)