C++ 投射向量<;T>;到向量<;常数T>;
我有一个C++ 投射向量<;T>;到向量<;常数T>;,c++,constants,C++,Constants,我有一个vector类型的成员变量(其中,T是一个自定义类,但也可以是int) 我有一个函数,我想从中返回一个指向这个向量的指针,但我不希望调用方能够更改向量或它的项。所以我希望返回类型是const vector* 我试过的铸造方法都不管用。编译器不断抱怨T与const T不兼容 这里有一些代码演示了我要做的事情的要点 vector<int> a; const vector<const int>* b = (const vector<const int>* )
vector
类型的成员变量(其中,T是一个自定义类,但也可以是int)
我有一个函数,我想从中返回一个指向这个向量的指针,但我不希望调用方能够更改向量或它的项。所以我希望返回类型是const vector*
我试过的铸造方法都不管用。编译器不断抱怨T与const T不兼容
这里有一些代码演示了我要做的事情的要点
vector<int> a;
const vector<const int>* b = (const vector<const int>* ) (&a);
向量a;
常量向量*b=(常量向量*)(&a);
这段代码不是为我编译的
提前谢谢 如果有一个
常量向量
,则不能修改容器,也不能修改容器中的任何元素。您不需要常量向量来实现这些语义。您可以这样强制转换:
b = reinterpret_cast<const std::vector<const int>*>(&a);
b=重新解释铸件(&a);
但我认为你不应该这样做,因为它不能保证有效,只编译除了James关于如何编译的回答之外,您应该注意const int
不是一个有效的类型,因为它是不可分配的。关于为什么向量
不能正确转换为向量
,即使T
可以转换为常量T
这是编程中经常出现的问题,无论是常量还是继承(派生对象的容器不能转换为基本对象的容器,即使包含的元素本身可以)。问题是每个元素都可以被转换,但是容器本身不能不破坏类型系统
如果允许您执行vector&vr=my\u vector\u of\u T
,则允许您通过vr
添加元素,并且这些元素的定义是恒定的。但同时,这些相同的元素将在my\u vector\u of \u T
中被别名为非常量元素,并可以通过该接口进行修改,从而打破类型系统中的常量
在将向量
转换为向量
的特定情况下,除了向向量
添加一个元素并查看常量元素在时间上的变化外,您可能不会注意到真正奇怪的效果,但是仍然要记住,给定两个相关的类型T1
和T2
,并且存在关系,在大多数情况下,试图将相同的关系应用于T1
和T2
的容器将破坏类型系统。编译器决定阻止此操作。然而,我们知道这是安全的,所以也许我们可以愚弄它:
const vector<const int>* b = (const vector<const int>* )(void *)(&a);
const vector*b=(const vector*)(void*)(&a);
为什么不返回const reference呢?因为OP使用了c风格的强制转换,这实际上是他们试图做的。当类型不相关且vector与vector或其他任何东西不相关时,c样式转换将进行重新解释转换。我应该在询问之前测试一下。我现在测试了它,它的工作原理和你描述的一样。谢谢,但如果我有向量呢?在大多数情况下,创建这样的向量是有意义的。@user311311311不,这样不安全。类型std::vector
无效,因为std::vector
要求T是可赋值的,而const int
不是。有趣的是,我使用了一个编译器,它会编译这个,直到你试图写入向量,然后你会得到一个非常模糊的编译器错误。“我们知道这是安全的”-哈哈,哇!“安全”从来都不是一个恰当的说法,除了[un/signed]char const*
之外,对任何东西都要重新解释[un/signed]cast
。如果您幸运并且愿意编写脆弱的不可移植代码,那么其他所有内容都是实现定义的。此外,(A)T const
不是有效的元素类型,并且(B)即使是,标准也不需要将两个实例化的成员变量按相同的顺序放置,因此即使reinterpret\u cast
在编译器上重新解释了对象表示,假设兼容成员在两个+1中的偏移量相等是愚蠢的,因为这样可以解释为什么即使容器中的引用是常量,更改容器也会导致问题。