【发布时间】:2015-03-18 18:05:07
【问题描述】:
有没有一种有效且安全的方式将std::vector<const Point*>& 转换为std::vector<Point*>&?
执行reinterpret_cast<std::vector<Point*>&>(constvec) 可能会正常工作,但可能是未定义的行为。
唯一的标准选项似乎是构造一个新的std::vector<Point*> 并手动添加每个const_casted 元素,但随后程序会不必要地为其分配内存。
编辑: 程序看起来像这样(简化):
class A {
private:
int some_data[10];
public:
template<typename Callback>
void algo(Callback callback) const {
std::vector<const int*> values { &some_data[0], &some_data[5], &some_data[3] };
// Class is const-correct internally, so only have const access to data here.
// Making it mutable is not easily possible in the real code,
// as there are constructs similar to iterator/const_iterator in the class hierarchy.
callback(values);
}
template<typename Callback>
void algo(Callback callback) {
// Hack to avoid copying the entire algorithm implementation
auto cb = [&](const std::vector<const int*>& vec) {
callback(....); // <--- should be const std::vector<int*>
}
static_cast<const A*>(this)->algo(cb);
}
};
另一种选择是在非常量变体中实现算法,然后在 const 变体中实现const_cast<A&>(*this).algo()。但这似乎更危险,因为 A 对象可能已创建为 const (const A a;),然后它是 UB。
【问题讨论】:
-
我明白为什么你可能想将
std::vector<Point*>转换为std::vector<const Point*>,但反过来看起来就很狡猾。如果您只是要忽略它,那么 const 有什么意义? -
我可以想象有合法的用例,但为了提出解决方案,我必须看看 OP 真正想要做什么。
-
@NeilKirk 即使这样也是有问题的,就好像你将
const Point*添加到强制转换向量中一样,你已经违反了常量正确性,因为现在你在原始向量中有一个Point*。这是可变的正方形不是矩形问题。如果 OP 将其向后,则可以创建向量内容的 const 正确 view。 -
@tmlen 所以你真正的问题是如何在创建同一函数的 const 和非 const 版本时避免重复代码?
-
@NeilKirk 它是
point *数据结构中的const point*。您将const point*添加到std::vector< point * >&的std::vector< const point *>&演员表中,它非法到达std::vector< point* >。
标签: c++ c++11 stl const-correctness const-cast