STL容器赋值和const指针

时间:2009-05-23 22:51:16

标签: c++ gcc stl const

编译:

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容器的逐点分配,除非我真的需要。

8 个答案:

答案 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中不可用。