"move" 和 "const ref&" 如何区分重载函数?
How ditinguish overload function with "move" and "const ref&"?
伙计们。
今天,我编写了一个模板 class,其中包含一个内部 class,其中有一个 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::map
的 operator[]
是 而不是 const
。如果该键不存在,则运算符调用将 放置 该键为默认初始化值。这就是为什么它不能 const
.
但是,将您的 getElementID
声明为 const
方法意味着它不能调用任何 非const
方法/运算符本身任何 非 mutable
字段的 和 。如您所见,mapper
未声明为 mutable
.
您可以通过以下方式解决此问题:
- 不将
getElementID
声明为 const
(不推荐)
- 不使用
operator[]
- 您可以使用 at()
代替,但要小心 - 如果没有密钥,operator[]
会插入它,但 at()
将 throw
一个 std::out_of_range
异常。您可能希望将这些调用包含在 try-catch
块中。
此外,我认为这只是一个打字错误,但您指的 mapper
和 _mapper
前后不一致。
伙计们。 今天,我编写了一个模板 class,其中包含一个内部 class,其中有一个 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::map
的 operator[]
是 而不是 const
。如果该键不存在,则运算符调用将 放置 该键为默认初始化值。这就是为什么它不能 const
.
但是,将您的 getElementID
声明为 const
方法意味着它不能调用任何 非const
方法/运算符本身任何 非 mutable
字段的 和 。如您所见,mapper
未声明为 mutable
.
您可以通过以下方式解决此问题:
- 不将
getElementID
声明为const
(不推荐) - 不使用
operator[]
- 您可以使用at()
代替,但要小心 - 如果没有密钥,operator[]
会插入它,但at()
将throw
一个std::out_of_range
异常。您可能希望将这些调用包含在try-catch
块中。
此外,我认为这只是一个打字错误,但您指的 mapper
和 _mapper
前后不一致。