首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >容器的const_casting元素类型

容器的const_casting元素类型
EN

Stack Overflow用户
提问于 2015-03-18 18:05:07
回答 2查看 208关注 0票数 3

是否有一种有效和安全的方法将std::vector<const Point*>&转换为std::vector<Point*>&

执行reinterpret_cast<std::vector<Point*>&>(constvec)可能工作正常,但可能是未定义的行为。

唯一的标准选项似乎是构建一个新的std::vector<Point*>并手动添加每个const_casted元素,但是程序将不必要地为它分配内存。

编辑:程序看起来如下(简化):

代码语言:javascript
复制
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变量实现const_cast<A&>(*this).algo()。但是这似乎更危险,因为A对象可能是以const (const A a;)的形式创建的,然后是UB。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-18 19:20:24

代码语言:javascript
复制
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,也可以不是const

票数 2
EN

Stack Overflow用户

发布于 2015-03-18 18:49:18

除了std::vector是一个标准库类之外,vector<Foo*>vector<Foo const*>类型可能是不同的,并且具有不同的大小。因此,虽然reinterpret_cast通常会工作,但它是形式上未定义的行为。无论如何,对reinterpret_cast的需求(除了在某些C风格的上下文中,比如Windows级别的编程中)通常是一个强烈的信号,表明人们走错了方向。

const和非const版本中都需要的方法的非平凡代码的情况下,一种解决方案是推迟到一个普通函数,例如static成员函数。

要做到这一点,有一些辅助机械是很方便的:

代码语言:javascript
复制
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;

然后您可以编写这样的类:

代码语言:javascript
复制
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 ) {}
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29129478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档