容器的const_cast元素类型
const_casting element type of container
是否有一种有效且安全的方法将std::vector<const Point*>&
强制转换为std::vector<Point*>&
?
执行reinterpret_cast<std::vector<Point*>&>(constvec)
可能会正常工作,但可能是未定义的行为。
唯一的标准选择似乎是构建一个新的std::vector<Point*>
并手动添加每个const_cast
ed元素,但程序会不必要地为其分配内存
编辑:程序如下(简化):
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_cast<A&>(*this).algo()
。但这似乎更危险,因为A
对象可能被创建为const(const A a;
),然后它就是UB。
template<class A, class B>
struct as_const_as { using type=B; }
template<class A, class B>
struct as_const_as<const A, B> { using type=const B; }
template<class A, class B>
using as_const_as_t=typename as_const_as<A,B>::type;
private:
template<class Self, class Callback>
static void algo(Self* self, Callback callback) {
// code using self instead of this
using int_t = as_const_as_t<Self, int>; // const or not depending on self
}
public:
template<class Callback>
void algo(Callback callback) {
algo( this, callback );
}
template<class Callback>
void algo(Callback callback) const {
algo( this, callback );
}
现在我们有两个外部方法algo
和一个static
方法,它将自己的类型作为模板类型,可以是const
也可以不是。
除了std::vector
是一个标准库类之外,类型vector<Foo*>
和vector<Foo const*>
可能有不同的专用化,并且具有不同的大小。因此,虽然reinterpret_cast
通常会起作用,但它在形式上是未定义的行为。无论如何,对reinterpret_cast
的需求(除了在某些C风格的上下文中,例如在Windows API级编程中)通常是一个强烈的信号,表明一个人走错了路。
在一个方法的非平凡代码在const
和非const
版本中都想要的情况下,一种解决方案是遵从普通函数,例如static
成员函数。
要做到这一点,有一些支持机制是很方便的:
struct Mutable{};
struct Const{};
template< class Constness, class Type >
struct With_t;
template< class Type > struct With_t<Mutable, Type>{ using T = Type; };
template< class Type > struct With_t<Const, Type>{ using T = Type const; };
template< class Constness, class Type >
using With = typename With_t<Constness, Type>::T;
然后你可以编写这样的类:
class Foo
{
private:
int something_;
template< class Constness >
static auto p( With<Constness, Foo>* that )
-> With<Constness, int>*
{ return &that->something_; } // In the real world some non-trivial code here.
public:
auto p() -> int* { return p<Mutable>( this ); }
auto p() const -> int const* { return p<Const>( this ); }
Foo( int const value ): something_( value ) {}
};
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- 如何理解C++标准N3337中的expr.const.cast子句8
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将元素添加到数组的线程安全函数?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 我想访问std::unique_ptr中的一个特定元素
- 如何通过 getter 函数删除矢量的元素?
- C++Cast运算符过载
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么