我有一个持有指向容器的指针的类。容器提供对其项目子集的访问。这是通过const和非const版本返回const /非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();
^ ~~~~~~~~~~~~~~~~~~
标记的代码编译得很好,但是,我的意图是给const访问通过const访问路径获得的项目(通过constobj
),因此const方法应该返回类型为Entity const*
的指针。将m_data
的类型从ContainerType*
更改为ContainerType
可以解决问题,但这不是我原始代码中的选项。
MyType::pointers() const
通过其属性MyContainer::pointers()
调用非const方法m_data
,其类型为MyContainer* const
(至少我认为是这样)。我显然需要输入MyContainer const*
。有没有一个优雅的解决方案来实现这一目标?std::vector<Entity const*> ret = static_cast<ContainerType const*>(m_data)->pointers();
这被认为是一个明智的解决方案吗?声明: 我希望这不是重复,似乎其他人之前必须遇到同样的问题。无论如何,我没有设法通过阅读关于SO的相关问题来解决这个问题。 (问题 Const correctness causing problems with containers for pointers?是不同的,它是关于指针的容器。这个问题似乎有关系,但答案并没有帮助我解决目前的问题。)
答案 0 :(得分:0)
写作时
m_data->pointers()
您正在调用相同的函数(非const函数),因为m_data定义为:
ContainerType* m_data;
即指向非const对象的指针。
使用constobj时,编译器将m_data视为const成员(不能更改constobj),但在此对象中,指针仍指向非const对象。
我不知道您的应用程序是什么,但您可以考虑添加一个新功能作为&#34; cpointers&#34;即使对象不是const,也要返回const指针。
编辑:我的意思是,像这样: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;
}
std::vector<const_pointer> cpointers() 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->cpointers(); // error!
return ret;
}
};
答案 1 :(得分:-1)
更改
std::vector<Entity const*> ret = m_data->pointers(); // error!
到
std::vector<Entity const*> ret =
(static_cast<const MyContainer<Entity>*>(m_data))->pointers(); // OK