无法将'const pointer const'传递给const ref

Tho*_* B. 12 c++ templates pointers const pass-by-const-reference

假设你有一组指针(是的......):

std::set<SomeType*> myTypeContainer;
Run Code Online (Sandbox Code Playgroud)

然后假设您要从SomeType的const方法搜索此集合:

bool SomeType::IsContainered() const
{
    return myTypeContainer.find(this) != myTypeContainer.end();
}
Run Code Online (Sandbox Code Playgroud)

这不起作用.方法中的thisptr是一个const SomeType *const,我不能把它放进去find.问题是find需要一个const-ref,在这种情况下,这意味着传递的指针被视为const,但不是它指向的东西.

有没有办法顺利解决这个问题(不改变设置的模板类型)?

Oli*_*liv 16

为了在有序容器中启用"混合"比较,您可以使用key_compare声明typename 的类型key_compare::is_transparent.

set的默认比较仿函数类是std::less<Key>.它不是"透明的".但std::less<void>是"透明的",并执行的任何参数的比较ab只要a<b是公形成.所以你可以定义自己的比较函子类型,或者你可以使用std::less<void>(或等价std::less<>):

set<SomeType*,std::less<>> myTypeContainer;
Run Code Online (Sandbox Code Playgroud)


son*_*yao 10

正如你所说,在const成员函数this变为const SomeType *(即指向const的指针)时,它不能被隐式转换为SomeType *(即指向非const的指针),这是预期的参数类型find.

您可以使用它const_cast来执行显式转换.

bool SomeType::IsContainered() const
{
    return myTypeContainer.find(const_cast<SomeType *>(this)) != myTypeContainer.end();
}
Run Code Online (Sandbox Code Playgroud)

如果铸造结果不用于修改,那将是安全的; 虽然std::set::find不会这样做.

  • @songyanyao我认为使用`const_cast`是没有必要的,我在答案中描述了一个更平滑的选择. (2认同)