编译:
int* p1;
const int* p2;
p2 = p1;
这不是:
vector<int*> v1;
vector<const int*> v2;
v2 = v1; // Error!
v2 = static_cast<vector<const int*> >(v1); // Error!
嵌套const指针的类型等价规则是什么?我认为转换是隐含的。此外,我宁愿不实现STL容器的逐点分配,除非我真的需要。
答案 0 :(得分:43)
无法直接分配。正如其他人所解释的那样,等价不是由指针类型建立的,而是由容器类型建立的。在这种情况下,vector不希望接受具有不同但兼容的元素类型的另一个向量。
没有真正的问题,因为您可以使用assign
成员函数:
v2.assign(v1.begin(), v1.end());
答案 1 :(得分:20)
从int*
到const int*
的转换内置于该语言中,但这些转换器的向量没有从一个转换为另一个。
答案 2 :(得分:7)
问题不是指针,而是两个向量的类型。模板化类型之间没有标准转换,例如示例中的v1和v2类型。
在以下代码中可能更容易看到:
#include <vector>
using namespace std;
int main() {
vector <char> cv;
vector <int> iv;
cv = iv; // error
}
答案 3 :(得分:4)
在C ++模板化的类中,模板的每个实例化都是一个完全不同的类 - vector<int *>
和vector<const int *>
之间存在的差异与vector<int *>
和{{1}之间存在很大差异或者任何其他两个类。
委员会可能会在vector<string>
上向vector
添加一个转换运算符Earwicker建议 - 您可以继续提供自己的功能实现:
vector<U>
并像这样使用它:
template <class A, class T>
vector<T> convert_vector(const vector<A> &other)
{
vector<T> newVector;
newVector.assign(other.begin(), other.end());
return newVector;
}
不幸的是,在C ++ 0x附带它的移动构造函数之前,这在性能方面会非常糟糕。
答案 4 :(得分:3)
完全可以编写自己的vector
版本,这是可能的。它与标准类型相同,但带有operator=
的模板版本,如下所示:
template <class A>
vector2<T> &operator=(const vector2<A> &other)
{
assign(other.begin(), other.end());
return *this;
}
其中T是整个类的元素类型,而A是可赋值给T的任何类型。
我不清楚为什么std::vector
没有这个。
答案 5 :(得分:2)
危险,除非您知道类型绝对兼容:
v2 = reinterpret_cast<std::vector<const int *> & >(v1);
大多数STL实现确实使用了一个特化,所有指针向量都共享相同的底层实现。这是因为(void *)通常与(int *)或任何其他指针类型相同。
答案 6 :(得分:2)
前面任何一个答案中没有提到的重要一点是,模板专业化使得无法在语言范围内实现这一点。考虑:
template<class T>
class Test
{
T t;
};
template<>
class Test<const int>
{
char array[1000];
};
因此Test<const int>
包含一个字符数组,而Test<int>
包含
单个int。
#include <iostream>
using namespace std;
int main()
{
Test<int> t1;
Test<const int> t2;
cout << sizeof(t1) << endl; // gives 4
cout << sizeof(t2) << endl; // gives 1000
return 0;
}
实际上vector<foo *>
和vector<const foo *>
可能差别不大
所有 - 特别是,它们可能具有相同的大小。但是,可能性
显式模板专业化意味着它们可能不同
引人注目,因此编译器不愿允许转换。
(这个答案主要是从http://bytes.com/topic/c/answers/449611-cast-vector-foo-vector-const-foo#post1717570)
复制的答案 7 :(得分:1)
Coercion by Member Template成语是解决问题的一种可能方法。实质上,添加了一个成员模板复制赋值运算符,它允许模板类参与相同的隐式类型转换(强制),否则只能在类模板的类型参数上进行。虽然这个习惯用法在其他地方的STL中使用,但它在std :: vector中不可用。