// Cat.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で、クライアントが変更可能な Cat を指すスマート ポインターを反復できるnon-const begin()
andを公開したいと考えています。non-const end()
そして、不変のものを指すイテレータconst begin()
をconst end()
返します。
次に、クライアントが const CatLibrary を反復するとき、ライブラリ内の Cat の内容を変更できることを心配する必要はありません。
しかし、const
追加されたメンバー関数begin()
は、ポインターが指す Cat ではなく、ポインターを const ポインターとして修飾するだけです。
ポインターが含まれていない場合、constness を持つベクトルは、反復子が constness を持つ要素を指すようにします。しかし、私はこの効果がスマートポインタが指す要素にも適用されることを望んでいます。
問題を解決するためのアプローチがありますが、将来の使用でどのような問題が発生するかわかりません。
const と nonconst で 2 つのベクトルを維持する
#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;
}
または、この種の constness の問題をベクトルのスマート ポインターで解決する別の解決策はありますか?