是什么导致了模板和继承的这个莫名其妙的编译器错误?
What is causing this baffling compiler error with templates and inheritance?
花了很长时间才将其提炼到可管理的大小,但这是代码:
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));
如果此代码按原样编译 (g++),我会收到编译器错误:
error: no matching function for call to 'ByteArray::Add(uint8_t [5], unsigned int)
但是,如代码中所述,删除一个函数后,代码编译正常,并且正确找到基 class 中的 Add 函数。这到底是怎么回事?
当名字Add
在classByteArray
的范围内找到时,名字查找停止,classArrayRef<uint8_t>
的范围不会被检查。
你可以将ArrayRef<uint8_t>::Add
引入到ByteArray
的范围内,就可以被发现并参与重载决议
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;
};
花了很长时间才将其提炼到可管理的大小,但这是代码:
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));
如果此代码按原样编译 (g++),我会收到编译器错误:
error: no matching function for call to 'ByteArray::Add(uint8_t [5], unsigned int)
但是,如代码中所述,删除一个函数后,代码编译正常,并且正确找到基 class 中的 Add 函数。这到底是怎么回事?
当名字Add
在classByteArray
的范围内找到时,名字查找停止,classArrayRef<uint8_t>
的范围不会被检查。
你可以将ArrayRef<uint8_t>::Add
引入到ByteArray
的范围内,就可以被发现并参与重载决议
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;
};