【发布时间】:2016-07-12 10:34:14
【问题描述】:
问题
我有一个类持有指向容器的指针。容器提供对其项目子集的访问。这是通过具有 const 和 non-const 版本的方法实现的,该方法返回 const/non-const 指针向量。以下代码摘自更复杂的设置的最小(不完全功能):
#include <vector>
struct Entity
{ int dummy; };
template <typename Value>
struct MyContainer
{
typedef Value* pointer;
typedef Value const* const_pointer;
std::vector<pointer> pointers() {
std::vector<pointer> ret;
return ret;
}
std::vector<const_pointer> pointers() const {
std::vector<const_pointer> ret;
return ret;
}
};
struct MyType
{
typedef MyContainer<Entity> ContainerType;
ContainerType* m_data; // I cannot make this a non-pointer attribute
std::vector<Entity*> pointers() {
std::vector<Entity*> ret = m_data->pointers();
return ret;
}
std::vector<Entity const*> pointers() const {
std::vector<Entity const*> ret = m_data->pointers(); // error!
return ret;
}
// std::vector<Entity*> pointers() const {
// std::vector<Entity*> ret = m_data->pointers();
// return ret;
// }
};
int main() {
MyType obj;
MyType const& constobj = obj;
std::vector<Entity*> pointers = obj.pointers();
std::vector<Entity const*> constpointers = constobj.pointers();
// std::vector<Entity*> constpointers = constobj.pointers();
}
Clang 3.8.0(也是3.5.2)报错:
error: no viable conversion from 'vector<pointer>' to 'vector<const Entity *>'
std::vector<Entity const*> ret = m_data->pointers();
^ ~~~~~~~~~~~~~~~~~~
commected 代码编译得很好,但是,我的意图是让 const 访问通过 const 访问路径(通过 constobj)获得的项目,因此 const 方法应该返回 Entity const* 类型的指针。将m_data 的类型从ContainerType* 更改为ContainerType 可以解决问题,但这不是我原始代码中的选项。
问题:
- 似乎
MyType::pointers() const通过其属性m_data调用了非常量方法MyContainer::pointers(),该属性的类型为MyContainer* const(至少我是这么认为的)。我显然需要输入MyContainer const*。有没有优雅的解决方案来实现这一目标? - 不太优雅的解决方案是将指针强制转换为 const 指针:
std::vector<Entity const*> ret = static_cast<ContainerType const*>(m_data)->pointers();这被认为是明智的解决方案吗? - 更笼统地说:我的设计有缺陷,还是我只是遗漏了一个细节?
免责声明: 我希望这不是重复的,看来其他人以前一定遇到过同样的问题。无论如何,我没有通过阅读有关 SO 的相关问题来解决这个问题。 (问题 Const correctness causing problems with containers for pointers? 不同,它是一个指针容器。这个问题似乎是相关的,但答案并没有帮助我解决我目前的问题。)
【问题讨论】:
-
m_data在您的调用中不是const,因此将再次调用非常量重载。 -
STL 采用了明确命名的常量方法和返回类型的设计,即
std::vector::cbegin()。它适合您吗? -
@Sergey 好点。值得作为答案发布。
-
@Sergey Hm.... 我不明白这如何解决我的问题。你的意思是我应该返回一个迭代器向量而不是一个指针向量?
-
如果您可以使用实验性功能,您可能会对
propagate_const感兴趣
标签: c++ pointers containers const-correctness