简体   繁体   English

C ++模板声明不可见

[英]C++ templates declaration is not visible

I have following code: 我有以下代码:

#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
    {

    }
};

Whenever I try to compile this particular code I have t 每当我尝试编译这个特定代码时,我都有

error: 'ReadIterator' has not been declared void read(ReadIterator& readIterator, std::size_t& len) override 错误:'ReadIterator'尚未声明为void read(ReadIterator&readIterator,std :: size_t&len)覆盖

error: 'WriteIterator' has not been declared void write(WriteIterator& writeIterator, std::size_t& len) override 错误:'WriteIterator'尚未声明为void write(WriteIterator&writeIterator,std :: size_t&len)覆盖

But if I change definition IntField class to class IntField : public Field or whatever that has certain type it compiles properly. 但是,如果我将定义IntField类更改为类IntField:public Field或具有特定类型的任何类型,它会正确编译。 Why the IntField can't be template in current context? 为什么IntField不能成为当前上下文中的模板?

This is a well-known problem. 这是一个众所周知的问题。 Compiler doesn't know that ReadIterator needs to come from the templated base class, as it tries to resolve the name during first step of template instantiation. 编译器不知道ReadIterator需要来自模板化基类,因为它试图在模板实例化的第一步中解析名称。 You might find more information on the 2-phase name lookup here: http://blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html 您可以在此处找到有关两阶段名称查找的更多信息: http//blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html

You need to be verbose here: 你需要在这里详细说明:

void read(typename Field<T>::ReadIterator& readIterator, std::size_t& len) override

Or, to save some typing: 或者,为了节省一些打字:

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

On a side note, your code doesn't make a huge lot of sense to me. 另外,您的代码对我来说并没有多大意义。 I would expect your IntField to not be a template: 我希望你的IntField 不是一个模板:

class IntField : public Field<int>
// ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM