質問編集履歴
3
追記2
title
CHANGED
File without changes
|
body
CHANGED
@@ -206,4 +206,35 @@
|
|
206
206
|
|
207
207
|
/* ... */
|
208
208
|
}
|
209
|
-
```
|
209
|
+
```
|
210
|
+
|
211
|
+
---
|
212
|
+
|
213
|
+
## 追記2
|
214
|
+
|
215
|
+
「いやいやそうじゃねぇよ,ごちゃごちゃ言ってないでまず最初にスタックから取り出せと」という方向のご指摘,もっともだと思います.
|
216
|
+
|
217
|
+
```C++
|
218
|
+
//何らかのタイミングでの処理
|
219
|
+
void XXX()
|
220
|
+
{
|
221
|
+
/* ... */
|
222
|
+
|
223
|
+
if( !TheStack.empty() )
|
224
|
+
{
|
225
|
+
//とにかく最初にやるべきことはこれだろ,と.
|
226
|
+
auto TakenOut = std::move( TheStack.top() ); //変な考えは捨てて取り出すべし
|
227
|
+
TheStack.pop(); //(ここでpopもやるかどうかというのは以降の実装の都合次第かもだが)
|
228
|
+
|
229
|
+
//とにかく取り出したなら,そもそもここで変な問題は起きない
|
230
|
+
TakenOut->DoSomething();
|
231
|
+
|
232
|
+
//---
|
233
|
+
|
234
|
+
//(必要なら TakenOut をスタックに再度積み直すだとかいう話はあるかもだが,それは今の「問題」とは別の話)
|
235
|
+
if( 何らかの判断 ){ TheStack.push( std::move(TakenOut) ); }
|
236
|
+
}
|
237
|
+
|
238
|
+
/* ... */
|
239
|
+
}
|
240
|
+
```
|
2
そもそもどうなのか?という指摘を受けての考えを追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -105,3 +105,105 @@
|
|
105
105
|
Owner.push( std::move( ToBePushed ) );
|
106
106
|
}
|
107
107
|
```
|
108
|
+
|
109
|
+
---
|
110
|
+
|
111
|
+
## 追記
|
112
|
+
|
113
|
+
「そもそも要素側からスタックを操作すること自体がどうなのか?」というご指摘,もっともだと思います.
|
114
|
+
その方面(要素側からスタックを操作しないようにする)で考えると,こんな↓形になりました.
|
115
|
+
こちらに関しても「いや,そうじゃねぇよ」とか「やるにしてもこうだろう」等々ご教示願えればありがたいです.
|
116
|
+
|
117
|
+
```C++
|
118
|
+
//要素が直接スタックを操作するのではなくて,
|
119
|
+
//要素からは「スタックをこのように操作したい」という要求を戻り値で返す.
|
120
|
+
//(→で,戻り値を受け取った側でスタックを操作する)
|
121
|
+
|
122
|
+
struct IStackElem;
|
123
|
+
|
124
|
+
//スタック
|
125
|
+
using Stack_t = std::stack< std::unique_ptr<IStackElem> >;
|
126
|
+
|
127
|
+
//スタックに対するPush操作
|
128
|
+
class Push
|
129
|
+
{
|
130
|
+
public:
|
131
|
+
//ctorでPushすべきものを指定
|
132
|
+
Push( std::unique_ptr<IStackElem> ToBePushed ) : m_ToBePushed( std::move(ToBePushed) ) {}
|
133
|
+
//操作実施
|
134
|
+
void Exec( Stack_t &Stk ){ if(m_ToBePushed)Stk.push( std::move(m_ToBePushed) ); }
|
135
|
+
private:
|
136
|
+
std::unique_ptr<IStackElem> m_ToBePushed;
|
137
|
+
};
|
138
|
+
|
139
|
+
//スタックに対するPop操作
|
140
|
+
class Pop
|
141
|
+
{
|
142
|
+
public:
|
143
|
+
//ctorでPopすべき回数を指定
|
144
|
+
Pop( size_t nPop=1 ) : m_nPop(nPop) {}
|
145
|
+
//操作実施
|
146
|
+
void Exec( Stack_t &Stk )
|
147
|
+
{
|
148
|
+
const size_t n = std::min( m_nPop, Stk.size() );
|
149
|
+
for( size_t i=0; i<n; ++i )Stk.pop();
|
150
|
+
}
|
151
|
+
private:
|
152
|
+
size_t m_nPop;
|
153
|
+
};
|
154
|
+
|
155
|
+
//スタックに対する操作要求
|
156
|
+
using StackOp = std::variant< Push, Pop >;
|
157
|
+
|
158
|
+
//スタックに積まれるやつ
|
159
|
+
struct IStackElem
|
160
|
+
{
|
161
|
+
virtual ~IStackElem() = default;
|
162
|
+
|
163
|
+
//※この型は専らスタックに積まれる使い方をされるという前提であって,
|
164
|
+
//このメソッドが呼ばれるときとは,自身がスタックのtopである場合である.
|
165
|
+
//
|
166
|
+
//戻り値として,所属スタックに対して実施されるべき操作シーケンスを返す.
|
167
|
+
virtual std::vector<StackOp> DoSomething() = 0;
|
168
|
+
};
|
169
|
+
|
170
|
+
//----------
|
171
|
+
//件の要素例の実装
|
172
|
+
struct Problem : public IStackElem
|
173
|
+
{
|
174
|
+
public:
|
175
|
+
Problem( size_t nPop, std::unique_ptr<IStackElem> ToBePushed )
|
176
|
+
: m_nPop(nPop), m_ToBePushed(std::move(ToBePushed))
|
177
|
+
{}
|
178
|
+
|
179
|
+
virtual std::vector<StackOp> DoSomething() override
|
180
|
+
{//m_nPop個だけ pop し,その後で m_ToBePushed を push したい
|
181
|
+
std::vector<StackOp> OPSeq;
|
182
|
+
OPSeq.emplace_back( Pop(m_nPop) );
|
183
|
+
OPSeq.emplace_back( Push( std::move(m_ToBePushed) ) );
|
184
|
+
return OPSeq;
|
185
|
+
};
|
186
|
+
|
187
|
+
private:
|
188
|
+
size_t m_nPop;
|
189
|
+
std::unique_ptr<IStackElem> m_ToBePushed;
|
190
|
+
};
|
191
|
+
|
192
|
+
//----------
|
193
|
+
//何らかのタイミングでの処理
|
194
|
+
void XXX()
|
195
|
+
{
|
196
|
+
/* ... */
|
197
|
+
|
198
|
+
if( !TheStack.empty() )
|
199
|
+
{
|
200
|
+
auto OPs = TheStack.top()->DoSomething();
|
201
|
+
for( auto &OP : OPs ) //返されてきた操作要求を実施する
|
202
|
+
{
|
203
|
+
std::visit( [&TheStack]( auto &OP ){ OP.Exec(TheStack); }, OP );
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
207
|
+
/* ... */
|
208
|
+
}
|
209
|
+
```
|
1
タグを増やした
title
CHANGED
File without changes
|
body
CHANGED
File without changes
|