我有一个成员变量std::set<T*> m_associates;,即非const原始指针的集合,只想检查另一个指针是否存在。为了保持const的正确性,我的函数如下所示:
bool MyClass::is_associated(const T* x) const
{
return (m_associates.find(x) != m_associates.end());
}但是,这并不能编译,因为x作为const T*传递,以指示x指向的值没有被函数更改,但是m_associates包含非const T*。
如果我从const参数中删除x,它会编译,但违反了const正确性.
将const添加到m_associates,也就是说,std::set<const T*> m_associates;也不是一个选项,因为我需要类中其他地方的非const指针。
我该怎么解决这个问题?这是(可能是唯一)应该使用const_cast的点吗?还是必须始终将所有参数T指针作为非const传递?
编辑:完全错误输出,编译器是clang++-8,代码在C++17中
error: no matching member function for call to 'find'
return (m_associates.find(x) != m_associates.end());
~~~~~~~~~~~~^~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:798:7: note: candidate function not viable: 1st argument ('const T *') would lose const qualifier
find(const key_type& __x) const
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:804:2: note: candidate function template not viable: 'this' argument has type 'const std::set<T *>', but method is not marked const
find(const _Kt& __x)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:794:7: note: candidate function not viable: 'this' argument has type 'const std::set<T *>', but method is not marked const
find(const key_type& __x)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:810:2: note: candidate template ignored: substitution failure [with _Kt = const T *]: no matching member function for call to '_M_find_tr'
find(const _Kt& __x) const
^发布于 2020-08-11 13:21:17
当前代码失败的原因是std::set<T>的默认std::set<T>是std::less<T>;这迫使两个参数都是用于比较的T --在本例中,是非const T*类型。由于const T*不能在不放弃一致性的情况下转换为T*,这将导致编译错误。
如果您正在使用C++14或更高版本,您可以重新定义您的std::set,以便使Compare模板类型是透明的比较器(一个推导底层类型以进行比较的比较器),例如std::set<T*, std::less<>>。这将启用std::set::find的重载,该重载将推导类型并将参数转发给比较器,这将使上述代码能够工作。
发布于 2020-08-11 13:20:10
在这种情况下,您可以抛弃const-ness of x,而不会产生任何不良影响。
除了发出设计缺陷的信号之外,您唯一需要注意的是,在丢弃const时,试图修改最初通过非const指针使用const声明的对象的行为是未定义的。这里不是这样的。
https://stackoverflow.com/questions/63358947
复制相似问题