"move"和"const ref&"如何使双丁吉过载起作用?



伙计们。 今天,我编写了一个模板类,其中包含一个具有 std::map 成员的内部类。

template <class ElementType>
class Manager
{
public:
size_t getElementIDInManager(ElementType* elem)const{
return _innerMapper->getElementID(elem);
}
void registerElement(ElementType* elem){
_innerMapper->register(elem);
}
public:
class Mapper{
size_t getElementID(ElementType* elem)const{
// !!! compile error here !!!
// doesnot find lvalue operator[]
// maybe "std::map::operator[](const unsigned _int64&)"
//      or "std::map::operator[](unsigned _int64&&)"
return _mapper[elem->getID()]; // "elem->getID()" return size_t value
// !!! even compile error if just call
return _mapper[0]; 
}
void register(ElementType* elem){
size_t size = _mapper.size();
_mapper[elem->getID()] = size; // assume this doesnot exists before
}
private:
std::map<size_t, size_t> mapper;
}_innerMapper;
};

然后,我用代码编译错误

class IDClass
{
public :
size_t getID() {return 1;} // just for test
};
typedef Manager<IDClass> IDManager;
IDManager mgr;
IDClass id;
mgr->register(id);  // compile pass
mgr->getElementIDInManager(id);  // compile pass, see last piece of code for error info

谁能给我一个提示? 当我想调用函数时,如何区分"const ref&"和"move&&"的函数? 就像 std::map::operator[] 一样。

这与const&&&之间的过载分辨率无关。出现此问题是因为您的getElementID方法const

size_t getElementID(ElementType* elem) const {
//                          notice here ^^^^

而且,令许多人惊讶的是,std::mapoperator[]并不const。如果该键不存在,运算符调用将使用默认初始化值替换该键。这就是为什么它不能const.

但是,将getElementID声明为const方法意味着它不能调用其自身任何mutable字段的任何const方法/运算符。如您所见,mapper未声明为mutable.

您可以通过以下方式解决此问题:

  • 未将getElementID声明为const(不推荐(
  • 不使用operator[]- 您可以使用at()代替,但要小心 - 如果没有密钥,operator[]插入它,但at()throwstd::out_of_range例外。您可能希望将这些调用包含在try-catch块中。

另外,我认为这只是一个错字,但您不一致地指的是mapper_mapper.

最新更新