调用 std::set<Type*>::find 时避免使用 const_cast
Avoiding const_cast when calling std::set<Type*>::find
有没有什么好的方法可以避免下面的 const_cast
,同时保持 const 的正确性?
如果没有 const_cast
,下面的代码将无法编译。 set::find
获取对集合的键类型的 const 引用,因此在我们的例子中它保证不会更改传入的指针值;但是,它不能保证不会更改指针指向的内容。
class C {
public:
std::set<int*> m_set;
bool isPtrInSet(const int* ptr) const
{
return m_set.find(const_cast<int*>(ptr)) != m_set.end();
}
};
Is there any good way to obviate the const_cast below, while keeping const correctness?
我不确定我要提出的建议是否符合 "good way"。但是,如果您不介意自己迭代集合的内容,则可以避免使用 const_cast
。请记住,这会将 O(log(N)) 操作转换为 O(N) 操作。
bool isPtrInSet(const int* ptr) const
{
for ( auto p : m_set )
{
if ( p == ptr )
{
return true;
}
}
return false;
}
我想解释为什么这是不可能的基本逻辑。
假设 set<int*>::find(const int*)
是合法的。然后您可以执行以下操作:
set<int*> s;
const int* p_const;
// fill s and p
auto it = s.find(p_const);
int* p = *it;
嗨,太棒了!您在未执行 const_cast
.
的情况下将 const int*
转换为 int*
是.
在 C++14 中,您可以使用自己的比较器,将 int const*
声明为 transparent。这将启用 template overload of find()
that can compare keys against arbitrary types. See this related SO question. And here's Jonathan Wakely's explanation.
有没有什么好的方法可以避免下面的 const_cast
,同时保持 const 的正确性?
如果没有 const_cast
,下面的代码将无法编译。 set::find
获取对集合的键类型的 const 引用,因此在我们的例子中它保证不会更改传入的指针值;但是,它不能保证不会更改指针指向的内容。
class C {
public:
std::set<int*> m_set;
bool isPtrInSet(const int* ptr) const
{
return m_set.find(const_cast<int*>(ptr)) != m_set.end();
}
};
Is there any good way to obviate the const_cast below, while keeping const correctness?
我不确定我要提出的建议是否符合 "good way"。但是,如果您不介意自己迭代集合的内容,则可以避免使用 const_cast
。请记住,这会将 O(log(N)) 操作转换为 O(N) 操作。
bool isPtrInSet(const int* ptr) const
{
for ( auto p : m_set )
{
if ( p == ptr )
{
return true;
}
}
return false;
}
我想解释为什么这是不可能的基本逻辑。
假设 set<int*>::find(const int*)
是合法的。然后您可以执行以下操作:
set<int*> s;
const int* p_const;
// fill s and p
auto it = s.find(p_const);
int* p = *it;
嗨,太棒了!您在未执行 const_cast
.
const int*
转换为 int*
是.
在 C++14 中,您可以使用自己的比较器,将 int const*
声明为 transparent。这将启用 template overload of find()
that can compare keys against arbitrary types. See this related SO question. And here's Jonathan Wakely's explanation.