如何用“ move”和“ const ref&”来区分重载函数?

时间:2019-09-15 16:03:42

标签: c++ move

伙计们。 今天,我编写了一个带有内部类的模板类,该内部类具有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 []一样。

1 个答案:

答案 0 :(得分:1)

这与const&&&之间的重载解析无关。出现问题是因为您的getElementID方法是const

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

,令许多人惊讶的是,std::map的{​​{1}}不是operator[] 。如果不存在该键,则操作员调用将使用默认初始化的值放置该键。这就是为什么它不能为const

但是,将您的const声明为getElementID方法意味着它不能调用任何 non-const 方法/自身的和< / strong>的任何const 字段。如您所见,mutable未声明为mapper

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

  • 不将mutable声明为getElementID(不推荐)
  • 不使用const-您可以改用operator[],但要小心-如果没有密钥,at()会插入它,但是operator[]会{ {1}}和at()异常。您可能需要将这些调用括在throw块中。

此外,我认为这只是一个错字,但您不一致地指的是std::out_of_rangetry-catch