c++ - CV 合格的数据成员和类型转换

标签 c++ constants

这个question引用 C++ 标准来证明 CV 限定类型的对齐方式和大小必须与非 CV 限定的等效类型相同。这看起来很明显,因为我们可以隐式转换 T 类型的对象。到 const T&使用static_castreinterpret_cast .

但是,假设我们有两种类型,它们都具有相同的成员变量类型,只是其中一种类型具有所有 const成员变量而另一个则没有。如:

typedef std::pair<T, T> mutable_pair;
typedef std::pair<const T, const T> const_pair;

这里,标准不允许我们生成 const_pair&来自 mutable_pair 的实例。也就是说,我们不能说:

mutable_pair p;
const_pair& cp = reinterpret_cast<const_pair&>(p);

这会产生未定义的行为,因为它没有被列为 reinterpret_cast 的有效使用。在标准中。然而,从概念上讲,似乎没有理由不允许这样做。

那么...为什么有人应该关心呢?你总是可以说:

const mutable_pair& cp = p;


好吧,如果您只希望一名成员成为 const,您可能会关心。合格的。如:

typedef std::pair<T, U> pair;
typedef std::pair<const T, U> const_first_pair;

pair p;
const_first_pair& cp = reinterpret_cast<const_first_pair&>(p);

显然这仍然是未定义的行为。然而,由于 CV 限定类型必须具有相同的大小和对齐方式,因此没有概念上的原因应该未定义它。

那么,标准是否有某种原因不允许这样做?或者只是标准委员会没有想到这个用例的问题?


对于任何想知道这可能有什么用途的人:在我的特定情况下,我遇到了一个用例,在该用例中,能够转换 std::pair<T, U> 会非常有用。到 std::pair<const T, U>& 。我正在实现一个专门的平衡树数据结构,它提供 log(N)按键查找,但内部每个节点存储多个元素。查找/插入/重新平衡例程需要对数据元素进行内部改组。 (该数据结构称为 T-tree 。)由于数据元素的内部改组会触发无数复制构造函数,从而对性能产生不利影响,因此如果可能的话,实现内部数据改组以利用移动构造函数是有益的。

不幸的是...我也希望能够提供一个满足 AssociativeContainer 的 C++ 标准要求的接口(interface),这需要 value_typestd::pair<const Key, Data> 。请注意const 。这意味着单个对对象无法移动(或者至少键不能移动)。它们必须被复制,因为 key 存储为 const对象。

为了解决这个问题,我希望能够在内部将元素存储为可变对象,但当用户通过迭代器访问它们时,只需将键强制转换为 const 引用。不幸的是,我无法转换 std::pair<Key, Data>std::pair<const Key, Data>& 。我无法提供某种返回包装类或其他内容的解决方法,因为这不能满足 AssociativeContainer 的要求.

因此就有这个问题。

那么,鉴于 CV 限定类型的大小和对齐要求必须与非 CV 限定的等效类型相同,是否有任何概念上的原因不允许进行此类强制转换?或者这只是标准编写者没有真正考虑到的事情?

最佳答案

将类型作为模板参数并不意味着您不会有不同的对齐方式,类内容可以更改,例如通过专门化或模板元编程。考虑:

template<typename T> struct X { int i; };
template<typename T> struct X<const T> { double i; };

template<typename T> struct Y {
    typename std::conditional<std::is_const<T>::value, int, double>::type x;
};

关于c++ - CV 合格的数据成员和类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38905834/

相关文章:

c++ - 函数指针不工作 (C++)

c++ - 如何解决同时设置成员的 setter/getter ?

c++ - 使用多态子类各自的方法

c++ - Qt中Q_PROPERTY的意义是什么?

.net - 在 .NET 和 C++ 中运行进程

c++ - 这对于 const 来说太不可改变了吗?

C++ 用常量值填充数组,循环和改变值

c - 尝试为常量分配新值

c++ - 编译单元之间共享的全局常量对象

c++ - 3d 数组声明导致段错误