質問内容
下記コードはメンバに
- 配列or動的配列への参照
- 配列のサイズを記すメモリへの参照
- 内部カウンタ変数(参照ではない)
を所持し、引数付きコンストラクタでそれら変数を初期化する
イテレータを作成しようとしたコードです。
登場するクラスは
クラス名 | 備考 |
---|---|
BaseIterator | 主にカウンタ変数にまつわる処理が記された基底クラス |
Iterator | 主に要素書き換えられるようにを参照で返す処理の記された派生クラス |
ConstIterator | 主に要素書き換えられないようにコピーで返す処理の記された派生クラス |
より構成されております。
しかし派生クラスの引数付きコンストラクタでコンパイルエラーが発生します。
エラー文(下記記載)を読む限りだと
派生クラスのコンストラクタでメンバ変数element_(参照)を操作できないと言っているようですが
対処法がわかりません。
どのように書けばメンバ変数element_をコンストラクタの引数で初期化できるのでしょうか
どうかご回答よろしくお願い致します。
c++
1#include <iostream> 2#include <memory> 3#include <cassert> 4 5/////////////////////////////////////////// 6// 7// Iterator基底クラス(抽象クラスではない) 8// 9/////////////////////////////////////////// 10template<typename Type, typename SizeType> 11class BaseIterator{ 12 protected: 13 Type& element_;// 配列の参照 14 SizeType& size_;// サイズの参照 15 SizeType counter_ = SizeType(0);// カウンタ 16 17 public: 18 BaseIterator()noexcept = delete; 19 virtual ~BaseIterator() = default; 20 21 auto operator++(int){// 後置++operator 22 this->counter_++; 23 assert(this->counter_ <= this->size_); 24 return *this; 25 } 26 27 decltype(auto) operator++(){// 前置++operator 28 ++this->counter_; 29 assert(this->counter_ <= this->size_); 30 return *this; 31 } 32 33 auto operator--(int){// 後置--operator 34 this->counter_--; 35 return *this; 36 } 37 38 decltype(auto) operator--(){// 前置--operator 39 --this->counter_; 40 return *this; 41 } 42 43 decltype(auto) operator=(const SizeType index)noexcept{// カウンターに数値歳入 44 assert(index <= this->size_); 45 this->counter_ = index; 46 return *this; 47 } 48 49 // 50 // ここから比較関連の処理 51 // 52 auto operator==(const BaseIterator<Type, SizeType>& itr)const noexcept{return this->counter_ == itr.counter_;} 53 auto operator!=(const BaseIterator<Type, SizeType>& itr)const noexcept{return this->counter_ != itr.counter_;} 54 auto operator>(const BaseIterator<Type, SizeType>& itr)const noexcept{return this->counter_ > itr.counter_;} 55 auto operator<(const BaseIterator<Type, SizeType>& itr)const noexcept{return this->counter_ < itr.counter_;} 56 auto operator>=(const BaseIterator<Type, SizeType>& itr)const noexcept{return this->counter_ >= itr.counter_;} 57 auto operator<=(const BaseIterator<Type, SizeType>& itr)const noexcept{return this->counter_ <= itr.counter_;} 58 59}; 60 61/////////////////////////////// 62// 63// Iteratorクラス(参照を返す) 64// 65/////////////////////////////// 66template<typename Type, typename SizeType> 67struct Iterator final:public BaseIterator<Type, SizeType>{ 68 //↓ここでコンパイルエラー発生 69 Iterator(Type& element, SizeType& size)noexcept:BaseIterator<Type, SizeType>::element_(element),BaseIterator<Type, SizeType>::size_(size){} 70 71 Iterator()noexcept = delete; 72 ~Iterator() = default; 73 74 // カウンタの指す要素の参照を返す 75 decltype(auto) operator*(){return this->element_[this->counter_];} 76 77 // 指定した要素の参照を返す 78 decltype(auto) operator[](const SizeType size){ 79 assert(size <= this->size_); 80 return this->element_[size]; 81 } 82}; 83 84/////////////////////////////////////////////////// 85// 86// ConstIteratorクラス(コピーされた別メモリを返す) 87// 88/////////////////////////////////////////////////// 89template<typename Type, typename SizeType> 90struct ConstIterator final:public BaseIterator<Type, SizeType>{ 91 //↓ここでコンパイルエラー発生 92 ConstIterator(Type& element, SizeType& size)noexcept:BaseIterator<Type, SizeType>::element_(element),BaseIterator<Type, SizeType>::size_(size){} 93 94 ConstIterator()noexcept = delete; 95 ~ConstIterator() = default; 96 97 // カウンタの指す要素のコピーを返す 98 auto operator*()const {return this->element_[this->counter_];} 99 100 // 指定した要素のコピーを返す 101 auto operator[](const SizeType size)const { 102 assert(size <= this->size_); 103 return this->element_[size]; 104 } 105}; 106 107/////////////// 108// 109// main関数 110// 111////////////// 112int main(){ 113 114 auto size = size_t(5); 115 auto mem = std::make_unique<int[]>(size); 116 117 auto itr = ConstIterator(mem, size); 118 119 return 0; 120} 121
エラー文
terminal
1[コードのパス]/main.cpp:90:88: error: typename specifier refers to non-type member 'element_' in 'BaseIterator<std::unique_ptr<int [], std::default_delete<int []> >, unsigned long>' 2 ConstIterator(Type& element, SizeType& size)noexcept:BaseIterator<Type, SizeType>::element_(element),BaseIterator<Type, SizeType>::size_(size){}// ここでコンパイルエラー発生 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~ 4[コードのパス]/main.cpp:114:16: note: in instantiation of member function 'ConstIterator<std::unique_ptr<int [], std::default_delete<int []> >, unsigned long>::ConstIterator' requested here 5 auto itr = ConstIterator(mem, size); 6 ^ 7[コードのパス]/main.cpp:14:15: note: referenced member 'element_' is declared here 8 Type& element_;// 配列の参照 9 ^ 10[コードのパス]/main.cpp:90:88: error: 'element_' is a protected member of 'BaseIterator<std::unique_ptr<int [], std::default_delete<int []> >, unsigned long>' 11 ConstIterator(Type& element, SizeType& size)noexcept:BaseIterator<Type, SizeType>::element_(element),BaseIterator<Type, SizeType>::size_(size){}// ここでコンパイルエラー発生 12 ^ 13[コードのパス]/main.cpp:14:15: note: must name member using the type of the current context 'ConstIterator<std::unique_ptr<int [], std::default_delete<int []> >, unsigned long>' 14 Type& element_;// 配列の参照 15 ^ 16[コードのパス]/main.cpp:90:136: error: typename specifier refers to non-type member 'size_' in 'BaseIterator<std::unique_ptr<int [], std::default_delete<int []> >, unsigned long>' 17 ConstIterator(Type& element, SizeType& size)noexcept:BaseIterator<Type, SizeType>::element_(element),BaseIterator<Type, SizeType>::size_(size){}// ここでコンパイルエラー発生 18 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~ 19[コードのパス]/main.cpp:15:19: note: referenced member 'size_' is declared here 20 SizeType& size_;// サイズの参照 21 ^ 22[コードのパス]/main.cpp:90:136: error: 'size_' is a protected member of 'BaseIterator<std::unique_ptr<int [], std::default_delete<int []> >, unsigned long>' 23 ConstIterator(Type& element, SizeType& size)noexcept:BaseIterator<Type, SizeType>::element_(element),BaseIterator<Type, SizeType>::size_(size){}// ここでコンパイルエラー発生 24 ^ 25[コードのパス]/main.cpp:15:19: note: must name member using the type of the current context 'ConstIterator<std::unique_ptr<int [], std::default_delete<int []> >, unsigned long>' 26 SizeType& size_;// サイズの参照 27
開発環境の備考
上記コードはすべてc++20でコンパイルするものとする。
ツールの種類 | ツールの名前 | バージョン |
---|---|---|
コンパイラ | clang++ | 10.0.0 |
OS | Linux Mint | 20.0 |
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/08/09 22:26 編集
退会済みユーザー
2020/08/11 07:17 編集
2020/08/11 07:41
退会済みユーザー
2020/08/11 08:40
2020/08/11 15:56
退会済みユーザー
2020/08/12 09:26 編集
2020/08/12 12:01
2020/08/12 12:02
退会済みユーザー
2020/08/13 04:00 編集