【发布时间】:2017-06-12 05:59:45
【问题描述】:
问题
以下代码无法在 C++11(或 C++14)中编译。我理解编译器的错误输出,但为什么标准不允许呢?
//main.cpp
#include <vector>
int main(void)
{
double a = 3.0;
double b = 3.0;
//It works with mere pointers
const double* ptrToConst = &a;
/***/ double* ptrToObj = &a;
// ptrToObj = ptrToConst; //Illegal : that's understandable…
ptrToConst = ptrToObj; //Works
//But the same doesn't work with vectors to pointers
std::vector<const double*> ptrsToConst = {&a, &b};
std::vector</***/ double*> ptrsToObj = {&a, &b};
// ptrsToObj = ptrsToConst; //Illegal : that's understandable
ptrsToConst = ptrsToObj; //Illegal : but why?!
}
错误来自ptrsToConst = ptrsToObj 行。实际上,似乎不可能将指针向量std::vector<T*> 复制到指向常量std::vector<const T*> 的指针向量中。请注意,在这两种情况下,指针本身都不是恒定的。
为什么这个操作是非法的? 最优雅的工作是什么?
更多详情
如果我通过调用clang++ --std=c++11 main.cpp 进行编译,则会显示以下错误消息:
main.cpp:19:17: error: no viable overloaded '='
ptrsToConst = ptrsToObj; //Illegal : but why?!
~~~~~~~~~~~ ^ ~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_vector.h:436:7: note: candidate
function not viable: no known conversion from 'vector<double *, allocator<double *>>' to 'const
vector<const double *, allocator<const double *>>' for 1st argument
operator=(const vector& __x);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_vector.h:448:7: note: candidate
function not viable: no known conversion from 'vector<double *, allocator<double *>>' to 'vector<const
double *, allocator<const double *>>' for 1st argument
operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_vector.h:470:7: note: candidate
function not viable: no known conversion from 'std::vector<double *>' to 'initializer_list<value_type>' (aka
'initializer_list<const double *>') for 1st argument
operator=(initializer_list<value_type> __l)
^
1 error generated.
对 gcc (g++) 进行相同尝试会产生类似的错误消息。
显然,向量的实现方式不允许我尝试执行的操作。然而,关于 const 正确性,这是一个安全的操作,对吧?
【问题讨论】:
-
std::vector<const double*>不是std::vector<double>的 cv 合格版本 -
std::vector<const double*>和std::vector<double>是完全不同且不相关的类型。特别是因为你不能保证两者都不是模板类的特殊实现。 -
如果
T和U是不同的类型,则不能将std::vector<T>分配给std::vector<U>,而不管T和U之间的关系如何。我猜std::vector的设计者没有考虑这个用法。 -
@imreal 实际上
std::vector<const double*>是一种允许(例如)插入/附加新成员的向量类型。但是,该新成员将“内部”存储为const double*,这意味着它必须是const double*或其他可以转换为它的类型,例如double*。 -
@Muscampester:你知道
double const*和double *const之间的区别吗? OP 想要第一个,而您建议的解决方案是第二个,这完全不一样。
标签: c++ c++11 pointers vector constants