【发布时间】:2014-09-28 23:26:39
【问题描述】:
//猫.h
class Cat
{public:
void const_meow() const{ ... };
void meow(){ ... };
};
class CatLibrary
{public:
std::vector<std::shared_ptr<Cat>>::iterator begin()
{
return m_cat_list.begin();
}
// compile error, the compiler complains cannot covert type
// from `std::vector<std::shared_ptr<Cat>>::const_iterator`
// to `std::vector<std::shared_ptr<const Cat>>::const_iterator`
std::vector<std::shared_ptr<const Cat>>::const_iterator begin() const
{
return m_cat_list.cbegin();
}
private:
std::vector<std::shared_ptr<Cat>> m_cat_list;
};
// main.cpp
CatLibrary cat_library;
cat_library.add(std::make_shared<Cat>());
cat_library.add(std::make_shared<Cat>());
for(auto& cat: cat_library )
{
cat->const_meow();
cat->meow();
}
for(const auto& cat: cat_library)
{
cat->const_meow();
cat->meow(); // hope to compile error due to invoking non_const method of Cat.
}
const CatLibrary& const_cat_library = cat_library;
for(auto& cat: const_cat_library )
{
cat->const_meow();
cat->meow(); // hope to compile error due to invoking non_const method of Cat.
}
const CatLibrary& const_cat_library = cat_library;
for(const auto& cat: const_cat_library )
{
cat->const_meow();
cat->meow(); // hope to compile error due to invoking non_const method of Cat.
}
我希望我的 CatLibrary 公开 non-const begin() 和 non-const end(),客户端可以在其中迭代指向可变 Cat 的智能指针。 const begin() 和 const end() 返回指向不可变的迭代器。
那么当客户端迭代 const CatLibrary 时,我不担心他会修改库中 Cat 的内容。
但是添加到我的成员函数begin() 中的const 仅将指针限定为 const 指针,而不是它指向的 Cat。
在不涉及指针的情况下,具有常量的向量使迭代器也指向具有常量的元素。但我希望这个效果也适用于智能指针指向的元素。
我有办法解决我的问题,但我不确定将来使用会出现什么问题。
在 const 和 nonconst 中维护两个向量
#include <iostream>
#include <memory>
#include <vector>
class Cat
{public:
void const_meow() const { std::cout << "meow" << std::endl;}
void meow() { std::cout << "meow" << std::endl;}
};
class CatLibrary
{public:
void add(std::shared_ptr<Cat> cat)
{
m_cat_list.push_back(cat);
m_cat_const_list.push_back(cat);
};
std::vector<std::shared_ptr<Cat>>::const_iterator begin()
{
return m_cat_list.begin();
}
std::vector<std::shared_ptr<const Cat>>::const_iterator begin() const
{
return m_cat_const_list.begin();
}
std::vector<std::shared_ptr<Cat>>::const_iterator end()
{
return m_cat_list.end();
}
std::vector<std::shared_ptr<const Cat>>::const_iterator end() const
{
return m_cat_const_list.end();
}
private:
std::vector<std::shared_ptr<Cat>> m_cat_list;
std::vector<std::shared_ptr<const Cat>> m_cat_const_list;
};
int main()
{
CatLibrary cat_library;
cat_library.add(std::make_shared<Cat>());
cat_library.add(std::make_shared<Cat>());
cat_library.add(std::make_shared<Cat>());
const CatLibrary& const_cat_library = cat_library;
for(auto& cat: cat_library)
{
cat->meow();
}
return 0;
}
或者有没有另一种解决方案来解决向量中智能指针的这种常量问题?
【问题讨论】:
-
我想我会在迭代期间使用类似 boost 的 transform_iterator 来进行转换,而不是维护两个向量。
标签: c++ constants smart-pointers const-iterator