可能值得说明为什么执行您想要的转换会违反 const 正确性:
#include <vector>
const int a = 1;
void addConst(std::vector<const int *> &v) {
v.push_back(&a); // this is OK, adding a const int* to a vector of same
}
int main() {
std::vector<int *> w;
int b = 2;
w.push_back(&b); // this is OK, adding an int* to a vector of same
*(w.back()) = 3; // this is OK, assigning through an int*
addConst(w); // you want this to be OK, but it isn't...
*(w.back()) = 3; // ...because it would make this const-unsafe.
}
问题是vector<int*>.push_back 采用指向非常量的指针(从现在开始我将其称为“非常量指针”)。这意味着,它可能会修改其参数的指针。特别是在向量的情况下,它可能会将指针交还给修改它的其他人。因此,您不能将 const 指针传递给 w 的 push_back 函数,即使模板系统支持它(它不支持),您想要的转换也是不安全的。 const-safety 的目的是阻止您将 const 指针传递给接受非 const 指针的函数,这就是它的工作方式。 C++ 要求您明确说明是否要执行不安全的操作,因此转换肯定不能是隐式的。事实上,由于模板的工作方式,根本不可能(见下文)。
我认为 C++ 原则上可以通过允许从 vector<T*>& 转换到 const vector<const T*>& 来保持 const-safety,就像 int ** 到 const int *const * 是安全的一样。但这是因为 vector 的定义方式:对于其他模板,它不一定是 const 安全的。
同样,理论上它可以允许显式转换。事实上,它确实允许显式转换,但仅限于对象,而不是引用;-)
std::vector<const int*> x(w.begin(), w.end()); // conversion
它不能做引用的原因是模板系统不能支持它。如果允许转换,将破坏的另一个示例:
template<typename T>
struct Foo {
void Bar(T &);
};
template<>
struct Foo<const int *> {
void Baz(int *);
};
现在,Foo<int*> 没有 Baz 功能。到底如何将Foo<int*> 的指针或引用转换为Foo<const int*> 的指针或引用?
Foo<int *> f;
Foo<const int *> &g = f; // Not allowed, but suppose it was
int a;
g.Baz(&a); // Um. What happens? Calls Baz on the object f?