CV合格数据成员和铸件 引用C++标准,证明CV限定类型的对齐和大小必须与非CV限定的等价类型相同。这似乎很明显,因为我们可以使用static\u cast或reinterpret\u cast将T类型的对象隐式强制转换为const T&

CV合格数据成员和铸件 引用C++标准,证明CV限定类型的对齐和大小必须与非CV限定的等价类型相同。这似乎很明显,因为我们可以使用static\u cast或reinterpret\u cast将T类型的对象隐式强制转换为const T&,c++,constants,C++,Constants,但是,假设我们有两种类型,它们都具有相同的成员变量类型,除了一种具有allconst成员变量,而另一种没有。例如: typedef std::pair<T, T> mutable_pair; typedef std::pair<const T, const T> const_pair; typedef std::pair<T, U> pair; typedef std::pair<const T, U> const_first_pair; pa

但是,假设我们有两种类型,它们都具有相同的成员变量类型,除了一种具有all
const
成员变量,而另一种没有。例如:

typedef std::pair<T, T> mutable_pair;
typedef std::pair<const T, const T> const_pair;
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);
这将产生未定义的行为,因为标准中未将其列为有效使用的
重新解释\u cast
。然而,从概念上讲,似乎没有理由不允许这样做

所以。。。为什么要有人关心?你可以说:

const mutable_pair& cp = p;

好吧,如果您只希望一个成员是
const
合格的,您可能会在意。例如:

typedef std::pair<T, T> mutable_pair;
typedef std::pair<const T, const T> const_pair;
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);
typedef std::pair对;
typedef std::pair const_first_pair;
对p;
const_first_pair&cp=重新解释铸造(p);
显然,这仍然是未定义的行为。但是,由于CV限定类型必须具有相同的大小和对齐方式,因此没有概念上的理由不定义

那么,有什么理由标准不允许这样做吗?或者仅仅是标准委员会没有想到这个用例


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

不幸的是。。。我也希望能够提供一个满足C++规范要求的接口,用于<代码>关联函数>代码>,这需要<代码> ValueSype类型< <代码> >代码> STD::配对< /代码>。注意
常量
。这意味着单个配对对象不能移动(或者至少关键点不能移动)。必须复制它们,因为密钥存储为
const
对象

为了解决这个问题,我希望能够在内部将元素存储为可变对象,但当用户通过迭代器访问它们时,只需将密钥转换为常量引用。不幸的是,我无法将
std::pair
转换为
std::pair&
。我不能提供某种返回包装类或其他东西的解决方法,因为这不符合
AssociationContainer
的要求

所以这个问题


同样,考虑到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;
};
模板结构X{int i;};
模板结构X{double i;};
模板结构{
typename std::conditional::type x;
};

“我们可以使用
static\u cast
reinterpret\u cast
T
类型的对象隐式强制转换为
const T&
”…为什么?如果必须键入强制转换操作,那么根据定义,它不是隐式强制转换。无论如何,这正是const_cast的目的,而不是其他任何一个;当然,它们会起作用,但为什么不使用语义上最相关的关键字呢?简单的答案是,不同的模板参数会创建不同且不兼容的模板类型,
T
T const
是不同的模板参数。。。但这似乎有点武断或循环,因此OP想知道为什么这两种模板类型不是特殊的,以产生不同但兼容的(可浇铸的)模板类型。这是一个很好的例子,说明了其中一个原因——当一个人开始思考时,可能会迅速增加在这里,cv鉴定被视为类型鉴别器。