次のコードを検討してください。
template <int N>
struct X
{
friend void f(X *) {}
};
int main()
{
f((X<0> *)0); // Error?
}
コンパイラは大きく反対しているようです。(MSVC08/10 はノー、GCC<4.5 はイエス、4.5 はノー、sun 5.1 はイエス、インテル 11.1 もイエス、comeau はノー (どちらも EDG))。
「C++ テンプレート - 完全なガイド」によると:
... 関連付けられたクラス内のフレンドのルックアップを含む呼び出しにより、実際にクラスがインスタンス化されると想定されています ... これは、C++ 標準を作成した人々によって明確に意図されていましたが、標準では明確に記述されていません。
標準で関連するセクションが見つかりませんでした。参照はありますか?
次のバリエーションを検討してください。
template <int N>
struct X
{
template <int M>
friend void f(X<M> *) {}
};
template <>
struct X<0>
{
};
int main()
{
X<1>();
f((X<0> *)0); // Error?
}
ここでの重要な問題は、によって注入された実行可能な関数がX<1>
ADL 中に表示されるX<0>
かどうかです。それらは関連していますか?上記のすべてのコンパイラは、このコードを受け入れますが、Comeau はリラックス モードでのみ受け入れます。これについて標準が何を言わなければならないのかもわかりません。
それについてどう思いますか?