質問するログイン新規登録

質問編集履歴

6

コメント追加

2015/12/15 07:58

投稿

Chironian
Chironian

スコア23274

title CHANGED
File without changes
body CHANGED
@@ -69,7 +69,7 @@
69
69
  namespace { namespace prv_impl
70
70
  {
71
71
  // privateな定義
72
- }}
72
+ }} // (←この2重かっこが見難くて悔しい)
73
73
 
74
74
  namespace
75
75
  {

5

例を修正

2015/12/15 07:58

投稿

Chironian
Chironian

スコア23274

title CHANGED
File without changes
body CHANGED
@@ -63,15 +63,21 @@
63
63
  文法的にも問題ないように感じますので、使えそうな気がします。
64
64
 
65
65
  ```C++
66
+ namespace myLib
67
+ {
68
+ namespace prv_impl {};
66
- namespace myLib { namespace {
69
+ namespace { namespace prv_impl
70
+ {
67
- // ここで外部公開クラスや関数定義
71
+ // privateな定義
72
+ }}
68
73
 
69
- namespace prv_impl {
74
+ namespace
75
+ {
70
- // ここで非公開内部クラスや関数定義
76
+ // publicな定義
71
77
  }
72
- }}
78
+ }
73
79
  ```
74
80
 
75
- 一瞬外部公開クラスを使えないようにも見える点に少し問題ありますが、使っても良さそうな気がします。
81
+ 一瞬外部公開クラスを使えないようにも見える点に少し問題ありますが、使っても良さそうな気がします。
76
82
 
77
83
  皆さんはどう思いますか?(それと、これは別質問にするべきですか?)

4

補足

2015/12/15 07:57

投稿

Chironian
Chironian

スコア23274

title CHANGED
File without changes
body CHANGED
@@ -48,6 +48,8 @@
48
48
  // でも myLib::prv_impl::hoge_impl(); はNG!
49
49
  }
50
50
  ```
51
+ ---
52
+ (引用終わり)
51
53
 
52
54
  > namespace prv_impl {}; // 実装が書いてある方のprv_implへのアクセス殺し。
53
55
 

3

追記

2015/12/15 06:11

投稿

Chironian
Chironian

スコア23274

title CHANGED
File without changes
body CHANGED
@@ -21,4 +21,55 @@
21
21
  異なる場所で内部クラスを定義する度にclassを別に定義する必要があるし、クラス内クラス・テンプレートは結構面倒なので、手間がかかりそう。
22
22
 
23
23
  **④**ヘッダの最後で内部名前空間名を#defineする。
24
- 解りやすくてよいけど、インクルード群の「最後」を決めることができないので使えない。
24
+ 解りやすくてよいけど、インクルード群の「最後」を決めることができないので使えない。
25
+
26
+ ---
27
+ 【②を検証】
28
+ http://tiri-tomato.hatenadiary.jp/entry/20130209/1360357831
29
+ に記載されている方法を確認しました。びっくりですが使えそうな感じがします。
30
+
31
+ 以下、上記ページから引用です。
32
+ ```C++
33
+ namespace myLib {
34
+ namespace {
35
+ // privateな実装
36
+ namespace prv_impl {
37
+ void hoge_impl() { /* ほにゃらら */ }
38
+ }
39
+ // publicな定義
40
+ void hoge() { prv_impl::hoge_impl(); }
41
+ }
42
+ namespace prv_impl {}; // 実装が書いてある方のprv_implへのアクセス殺し。
43
+ }
44
+ ```
45
+ ```C++
46
+ void func() {
47
+ myLib::hoge(); // これはOK。
48
+ // でも myLib::prv_impl::hoge_impl(); はNG!
49
+ }
50
+ ```
51
+
52
+ > namespace prv_impl {}; // 実装が書いてある方のprv_implへのアクセス殺し。
53
+
54
+ を書く場所が気になったのですが、namespace myLibの先頭へ移動しても意図通りでした。
55
+ また、msvc2015, MinGW 4.9.2, MinGW 5.2.0全てで、
56
+ 1) myLib内の無名namespaceから、hoge_impl()をアクセス可
57
+ 2) myLib外部からは、hoge_impl()はundefined symbol
58
+ 3) myLib直下からは、hoge_impl()するとprv_implが曖昧
59
+ となりました。
60
+
61
+ 文法的にも問題ないように感じますので、使えそうな気がします。
62
+
63
+ ```C++
64
+ namespace myLib { namespace {
65
+ // ここで外部公開クラスや関数定義
66
+
67
+ namespace prv_impl {
68
+ // ここで非公開な内部クラスや関数定義
69
+ }
70
+ }}
71
+ ```
72
+
73
+ 一瞬外部公開クラスを使えないようにも見える点に少し問題ありますが、使っても良さそうな気がします。
74
+
75
+ 皆さんはどう思いますか?(それと、これは別質問にするべきですか?)

2

追記

2015/12/15 06:09

投稿

Chironian
Chironian

スコア23274

title CHANGED
File without changes
body CHANGED
@@ -2,4 +2,23 @@
2
2
 
3
3
  内部的なクラス・テンプレートが多数あるのですが、混乱を招くだけなのでこれらをユーザに使わせたくないのです。普通にドキュメントで説明しないだけでも一定の効果はあると思いますが、可能であれば「使えない」、もしくは、「使いにくく」したいと考えてます。
4
4
 
5
- 必須要件ではないし、C++言語仕様上無理っぽい気がするので諦める方向なのですが、もし、何か使えそうなテクニックをご存知の方がいれば、ぜひ教えて下さい。
5
+ 必須要件ではないし、C++言語仕様上無理っぽい気がするので諦める方向なのですが、もし、何か使えそうなテクニックをご存知の方がいれば、ぜひ教えて下さい。
6
+
7
+ ---
8
+ 【追記】
9
+ privateな名前空間だよなと思いつつ、流石にあり得ないので検索することに思い至って無かったのですが、検索してみたらいくつか当たりました!
10
+ http://tiri-tomato.hatenadiary.jp/entry/20130209/1360357831
11
+ http://oshiete.goo.ne.jp/qa/6902744.html
12
+
13
+ catsforepawさんの回答も含めて今のところ下記方法が考えられそうです。
14
+
15
+ **①**内部用の名前空間をわけ、長い名前をつけてて使い難くする。
16
+
17
+ **②**無名名前空間を途中にかまして、使えなくする。
18
+ ただし、上書きするための名前空間定義の場所が気になる。最後にしないとダメかも? 後ほど確認予定。
19
+
20
+ **③**全部privateなclass内に定義し、friend指定する。
21
+ 異なる場所で内部クラスを定義する度にclassを別に定義する必要があるし、クラス内クラス・テンプレートは結構面倒なので、手間がかかりそう。
22
+
23
+ **④**ヘッダの最後で内部名前空間名を#defineする。
24
+ 解りやすくてよいけど、インクルード群の「最後」を決めることができないので使えない。

1

pImplイデオムへの言及を削除

2015/12/15 05:36

投稿

Chironian
Chironian

スコア23274

title CHANGED
File without changes
body CHANGED
@@ -1,6 +1,5 @@
1
1
  C++ライブラリを開発してます。ほとんどのクラスがテンプレートです。
2
2
 
3
3
  内部的なクラス・テンプレートが多数あるのですが、混乱を招くだけなのでこれらをユーザに使わせたくないのです。普通にドキュメントで説明しないだけでも一定の効果はあると思いますが、可能であれば「使えない」、もしくは、「使いにくく」したいと考えてます。
4
- しかし、明示的実体化できないクラス・テンプレートなのでpImplイデオムでは隠せないと思います。
5
4
 
6
5
  必須要件ではないし、C++言語仕様上無理っぽい気がするので諦める方向なのですが、もし、何か使えそうなテクニックをご存知の方がいれば、ぜひ教えて下さい。