読者です 読者をやめる 読者になる 読者になる

チリペヂィア

リンクフリー。サンプルコードなどは関連記事内でライセンスについて明示されない限り商用利用なども自由に行って構いませんが、自己責任でお願いします。またこれら日記内容の著作権自体は放棄していません。引用部分については引用元の権利に従ってください。

namespaceでprivateはやっぱりできないと考えるべきなのかしら。

こーいう方法があるようです。
http://okwave.jp/qa/q6902744.html

ちょと読みにくかったので書き直します。

namespace myLib {
	namespace {
		// privateな実装
		namespace prv_impl {
			void hoge_impl() { /* ほにゃらら */ }
		}
		// publicな定義
		void hoge() { prv_impl::hoge_impl(); }
	}
	namespace prv_impl {}; // 実装が書いてある方のprv_implへのアクセス殺し。
}
void func() {
	myLib::hoge(); // これはOK。
	// でも myLib::prv_impl::hoge_impl(); はNG!
}

これはVC2010でコンパイル通りました。最初さっぱり意味がわからなかったので、さらっとネットをさらってみましたが多分今のところはギリギリ言語仕様範囲内のように思いました。これは「名前の無いnamespace同士を同じもののように連結しながら、外側からもアクセス可能な文法を簡単に用意したいから、無名namespaceは暗黙usingされるのに等価にしちゃえ」を逆手に取った方法なのです。

リクエストがあればもう少し細かく解説しますが…うーむ。

なんというか、環境によっては通らないとかあっても別に驚かないくらいのグレーゾーンです。なんせusingさせた後で新しく定義を書き足して衝突させて消してますからね。確かに優先順は自明なのですが。

なんかぶっ飛んだコンパイラで後発のmyLib::prv_implの出現時に先発のmyLib::<無名>::prv_implを上書きしないでミックスさせるような奴には突破されちゃいますね(そこでstruct prv_impl{}でstatic関数にしたらミックスは起こりえませんが、そんなコンパイラだったらそれはそれで衝突時に警告なり出そう)。また0xのinline namespaceに対応するコンパイラなら無名namespaceはinline namespace{}にするべきです(暗黙usingの明示的指定)。inlineをdefineマクロでON/OFFするくらいで対応できますが、少なくともこのへんの諸々はコンパイラの実装に依存します。とは言え、確かに「勝手にusingされる」以上に規則的でスマートな実装はありうるのかと言われると、まず無いだろうなーとも思うのですが…

参考

これがVCで通る理由を説明してくれるページ(VCの簡易的なnamespaceの実装について)
[MSDN]無名の名前空間

ちーなーみ^にー?

あまり関係はないのですがVCの採用する簡易実装では正しく0xの仕様を満たさない一例を取り上げているサイトがコチラ。
無名(匿名)名前空間の不思議な定義

なんというか、伝説の呪われた神器ライブラリLoki的な行き過ぎの趣味っぽさが漂います。

要するにこのprivate namespaceの方法は、(少なくとも個人的には)現在実装が追いついてなかったり将来に向けて進化を続けそうな部分に大きく依存するところにまだちょっと気の早いバッドノウハウ臭を覚えたのです(でも妙案こそ得てしてそんなものだとは思う)。namespaceの仕様がもう少し枯れてくればこれでいいような気はしますが。考えすぎかしら。