質問編集履歴

5

追記

2016/12/22 03:09

投稿

Chironian
Chironian

スコア23272

test CHANGED
File without changes
test CHANGED
@@ -1,5 +1,13 @@
1
1
  【追記】不可能な内容かも知れないのですが、まだ少しだけ希望を持っていますので、「解決済」には致しません。もし、解をお持ちの方がいらっしゃいましたら、是非ご教授下さい。
2
2
 
3
+
4
+
5
+ 【2016/12/22追記】
6
+
7
+ 長らく放置してしまいました。断念したのでクローズします。
8
+
9
+
10
+
3
11
  ---
4
12
 
5
13
 

4

追記

2016/12/22 03:09

投稿

Chironian
Chironian

スコア23272

test CHANGED
File without changes
test CHANGED
@@ -1,3 +1,9 @@
1
+ 【追記】不可能な内容かも知れないのですが、まだ少しだけ希望を持っていますので、「解決済」には致しません。もし、解をお持ちの方がいらっしゃいましたら、是非ご教授下さい。
2
+
3
+ ---
4
+
5
+
6
+
1
7
  今、あるライブラリをC++11準拠の条件で開発してます。
2
8
 
3
9
  コンパイラは、msvc 2015とg++4.9.2以降を想定しています。

3

getValue\(\)が不要だったので削除

2015/11/18 05:33

投稿

Chironian
Chironian

スコア23272

test CHANGED
File without changes
test CHANGED
@@ -156,8 +156,6 @@
156
156
 
157
157
  public:
158
158
 
159
- virtual int getValue() = 0;
160
-
161
159
  virtual void print(int aValue) = 0;
162
160
 
163
161
  };
@@ -204,8 +202,6 @@
204
202
 
205
203
 
206
204
 
207
- int getValue() {return value;}
208
-
209
205
  void print(int aValue)
210
206
 
211
207
  {

2

typo修正と説明文の修正

2015/11/12 03:25

投稿

Chironian
Chironian

スコア23272

test CHANGED
File without changes
test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  このような場合、通常はLib<>クラスを基底クラスから派生するようにし、Func()関数を仮想関数にすると思います。しかし、関数テンプレートを仮想関数にすることができませんので、Client()を非テンプレート化できないのです。
14
14
 
15
- 仮想関数にわる何か良い方法はないでしょうか?
15
+ 仮想関数にわる何か良い方法はないでしょうか?
16
16
 
17
17
 
18
18
 
@@ -128,7 +128,9 @@
128
128
 
129
129
  このタイミングではLib<>がコンストラクトされていないので、動的な方法ではvalueをリストできないのです。
130
130
 
131
+
132
+
131
- こんなに複雑なことをしている目的はこのLib<>のンストラクタで使われているTypeのリストを取り出すことです。
133
+ こんなに複雑なことをしている目的はLib<>のンスタンスで使われているTypeのリストをvalueと関連づけて、Lib<>のコンストラクタ内で取り出せるようにことです。
132
134
 
133
135
  ```C++
134
136
 

1

説明の補足

2015/11/12 02:26

投稿

Chironian
Chironian

スコア23272

test CHANGED
File without changes
test CHANGED
@@ -48,7 +48,225 @@
48
48
 
49
49
  std::cout << value << " :" << typeid(aInstance).name() << "\n";
50
50
 
51
+ // 実際にはここで下記シングルトンを生成しています
52
+
53
+ // template<typename Type, int value>
54
+
55
+ // class Singleton {};
56
+
57
+ }
58
+
59
+ };
60
+
61
+ ```
62
+
63
+ ```C++
64
+
65
+ // main.cpp
66
+
67
+ #include "lib.h"
68
+
69
+
70
+
71
+ class Foo {};
72
+
73
+
74
+
75
+ template<int value>
76
+
77
+ void Client(Lib<value>* aLib)
78
+
79
+ {
80
+
81
+ aLib->Func(123);
82
+
83
+ aLib->Func(123.0);
84
+
85
+ aLib->Func(Foo());
86
+
87
+ }
88
+
89
+
90
+
91
+ int main()
92
+
93
+ {
94
+
95
+ Lib<456> lib_456;
96
+
97
+ Lib<789> lib_789;
98
+
99
+
100
+
101
+ Client(&lib_456);
102
+
103
+ Client(&lib_789);
104
+
105
+ }
106
+
107
+ ```
108
+
109
+
110
+
111
+ ---
112
+
113
+
114
+
115
+ 【追記】
116
+
117
+ サンプルの説明が不適切だったので、Func()内のコメントを修正しました。
118
+
119
+
120
+
121
+ また、何のためにSingleton<Type, value>を作っているのか分からないと思います。
122
+
123
+ かなり長くなってしまうのですか、実際に使っているものに近いサンプルを以下に示します。
124
+
125
+ boostで使われているテクニックですが、シングルトン生成時、スタティック変数Instanceをこのように初期化することで、main()関数が走る前にこのシングルトンが生成されます。
126
+
127
+ これにより、Lib<>のコンストラクタで、Lib<>::Func()に渡されるTypeの型リストへアクセスできるようになるのです。
128
+
129
+ このタイミングではLib<>がコンストラクトされていないので、動的な方法ではvalueをリストできないのです。
130
+
131
+ こんなに複雑なことをしている目的はこのLib<>のコンストラクタで使われているTypeのリストを取り出すことです。
132
+
133
+ ```C++
134
+
135
+ // lib.h
136
+
137
+ #include <iostream>
138
+
139
+ #include <typeinfo>
140
+
141
+ #include <vector>
142
+
143
+
144
+
145
+ class BaseSingleton;
146
+
147
+ std::vector<BaseSingleton*> TypeList;
148
+
149
+
150
+
151
+ class BaseSingleton
152
+
153
+ {
154
+
155
+ public:
156
+
157
+ virtual int getValue() = 0;
158
+
159
+ virtual void print(int aValue) = 0;
160
+
161
+ };
162
+
163
+
164
+
165
+ template<typename Type, int value>
166
+
167
+ class Singleton : public BaseSingleton
168
+
169
+ {
170
+
171
+ private:
172
+
173
+ static Singleton& Instance;
174
+
175
+ Singleton()
176
+
177
+ {
178
+
179
+ std::cout << "Singleton() : " << value << " :" << typeid(Type).name() << "\n";
180
+
181
+ }
182
+
183
+ static void use(const Singleton&) {}
184
+
185
+
186
+
187
+ public:
188
+
189
+ static Singleton& getInstance()
190
+
191
+ {
192
+
193
+ static Singleton instance;
194
+
195
+ use(Instance);
196
+
197
+ TypeList.push_back(&instance);
198
+
199
+ return instance;
200
+
201
+ }
202
+
203
+
204
+
205
+ int getValue() {return value;}
206
+
207
+ void print(int aValue)
208
+
209
+ {
210
+
211
+ if (aValue == value)
212
+
213
+ std::cout << "print() : " << value << " :" << typeid(Type).name() << "\n";
214
+
215
+ }
216
+
217
+
218
+
219
+ // コピー/ムーブ禁止
220
+
221
+ Singleton(const Singleton&) = delete;
222
+
223
+ Singleton( Singleton&&) = delete;
224
+
225
+ Singleton& operator=(const Singleton&) = delete;
226
+
227
+ Singleton& operator=( Singleton&&) = delete;
228
+
229
+ };
230
+
231
+ template<typename Type, int value>
232
+
233
+ Singleton<Type, value>& Singleton<Type, value>::Instance = Singleton<Type, value>::getInstance();
234
+
235
+
236
+
237
+ template<int value>
238
+
239
+ struct Lib
240
+
241
+ {
242
+
243
+ Lib()
244
+
245
+ {
246
+
247
+ // ここで自分で使われている型のリストを抽出してます
248
+
249
+ for (auto& itr : TypeList) {
250
+
251
+ itr->print(value);
252
+
253
+ }
254
+
255
+ }
256
+
257
+
258
+
259
+ template<typename Type>
260
+
261
+ void Func(const Type& aInstance)
262
+
263
+ {
264
+
265
+ Singleton<Type, value>::getInstance();
266
+
267
+
268
+
51
- // 実際SFINAEを使ってTypeで分岐し、下記のようなイメージの処理をします
269
+ // にSFINAEを使ってTypeで分岐し、下記のようなイメージの処理をします
52
270
 
53
271
  // 組み込み型の時は特定の処理を行う
54
272
 
@@ -74,8 +292,6 @@
74
292
 
75
293
  class Foo {};
76
294
 
77
-
78
-
79
295
  template<int value>
80
296
 
81
297
  void Client(Lib<value>* aLib)
@@ -92,20 +308,108 @@
92
308
 
93
309
 
94
310
 
311
+ class Bar {};
312
+
313
+ template<int value>
314
+
315
+ void Client2(Lib<value>* aLib)
316
+
317
+ {
318
+
319
+ aLib->Func("string");
320
+
321
+ aLib->Func(Bar());
322
+
323
+ }
324
+
325
+
326
+
95
327
  int main()
96
328
 
97
329
  {
98
330
 
331
+ std::cout << "---------- Start main()\n";
332
+
333
+
334
+
335
+ std::cout << "pre Lib<456>\n";
336
+
99
337
  Lib<456> lib_456;
100
338
 
339
+ std::cout << "post Lib<456>\n";
340
+
341
+ Client(&lib_456);
342
+
343
+
344
+
345
+ std::cout << "pre Lib<789>\n";
346
+
101
347
  Lib<789> lib_789;
102
348
 
103
-
104
-
105
- Client(&lib_456);
349
+ std::cout << "post Lib<789>\n";
106
350
 
107
351
  Client(&lib_789);
108
352
 
353
+
354
+
355
+ std::cout << "pre Lib<-123>\n";
356
+
357
+ Lib<-123> lib_m123;
358
+
359
+ std::cout << "post Lib<-123>\n";
360
+
361
+ Client2(&lib_m123);
362
+
109
363
  }
110
364
 
111
365
  ```
366
+
367
+ msvc2015での実行結果は下記の通りです。
368
+
369
+
370
+
371
+ Singleton() : 456 :int
372
+
373
+ Singleton() : 456 :double
374
+
375
+ Singleton() : 456 :class Foo
376
+
377
+ Singleton() : 789 :int
378
+
379
+ Singleton() : 789 :double
380
+
381
+ Singleton() : 789 :class Foo
382
+
383
+ Singleton() : -123 :char [7]
384
+
385
+ Singleton() : -123 :class Bar
386
+
387
+ ---------- Start main()
388
+
389
+ pre Lib<456>
390
+
391
+ print() : 456 :int
392
+
393
+ print() : 456 :double
394
+
395
+ print() : 456 :class Foo
396
+
397
+ post Lib<456>
398
+
399
+ pre Lib<789>
400
+
401
+ print() : 789 :int
402
+
403
+ print() : 789 :double
404
+
405
+ print() : 789 :class Foo
406
+
407
+ post Lib<789>
408
+
409
+ pre Lib<-123>
410
+
411
+ print() : -123 :char [7]
412
+
413
+ print() : -123 :class Bar
414
+
415
+ post Lib<-123>