2

It took quite a while to distill this down to a manageable size, but here's the code:

template<typename T = uint8_t> struct ArrayRef {
  T* data;
  size_t size;
  size_t capacity;

  ArrayRef<T>(T* d, size_t c, size_t size) : data(d), size(size), capacity(c) {}

  void Add(T* buffer, size_t size) { }
};

struct ByteArray : ArrayRef<uint8_t> {
  ByteArray(uint8_t* d, size_t c, size_t size) : ArrayRef<uint8_t>(d,c,size) {}

  // If this function is removed, the test code can find the inherited Add function
  template <typename T> void Add(T& item) { }
};

void Test() {
  uint8_t ibuf[20];
  ByteArray ba(ibuf, 20, 0);
  uint8_t buf[5];
  ba.Add(buf, sizeof(buf));

If this code is compiled as is (g++), I get the compiler error:

error: no matching function for call to 'ByteArray::Add(uint8_t [5], unsigned int)

But, as noted in the code, when the one function is removed, the code compiles fine and the Add function in the base class is found correctly. What exactly is going on here?

Andrew Voelkel
  • 513
  • 4
  • 10

1 Answers1

2

When the name Add is found at the scope of class ByteArray, name lookup stops, the scope of class ArrayRef<uint8_t> won't be checked.

You can introduce ArrayRef<uint8_t>::Add into the scope of ByteArray, then it could be found and take part in overload resolution.

struct ByteArray : ArrayRef<uint8_t> {
  ByteArray(uint8_t* d, size_t c, size_t size) : ArrayRef<uint8_t>(d,c,size) {}

  // If this function is removed, the test code can find the inherited Add function
  template <typename T> void Add(T& item) { }

  using ArrayRef<uint8_t>::Add;
};
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • Why does the name lookup stop with the method signatures are different? That doesn't make sense to me. It seems this happens only with templates? – Andrew Voelkel Mar 13 '22 at 17:16
  • @AndrewVoelkel Name lookup doesn't consider signature, only the name `Add`. And this happens with non-templates too. Overload resolution considers signature, it happens after name lookup. – songyuanyao Mar 14 '22 at 01:26
  • Wow, you are right. I can't believe that I haven't run into that in all these years. It still doesn't make sense that is has to be this way, but I'm sure there is some obscure reason. Thank you! – Andrew Voelkel Mar 14 '22 at 17:15