バックグラウンド
C ++ 03では、テンプレート引数として使用されるシンボルには外部リンケージが必要です。この前の質問で検討したように、この制限はC++11で削除されました。
C ++ 03では、テンプレート引数に内部リンクを設定できませんでした。
[C++03: 14.6.4.2/1]:
テンプレートパラメータに依存する関数呼び出しの場合、関数名が非修飾IDであるが、テンプレートIDではない場合、候補関数は、次の場合を除いて、通常のルックアップルール(3.4.1、3.4.2)を使用して検出されます。
- 非修飾名ルックアップ(3.4.1)を使用したルックアップの部分では、テンプレート定義コンテキストからの外部リンケージを持つ関数宣言のみが見つかります。
- 関連する名前空間(3.4.2)を使用したルックアップの一部では、テンプレート定義コンテキストまたはテンプレートインスタンス化コンテキストのいずれかで見つかった外部リンケージを持つ関数宣言のみが見つかります。
[..]
これは、C ++ 11で変更されました(問題#561:「依存名ルックアップの内部リンケージ関数」 ):
[C++11: C.2.6]:
14.6.4.2
変更:内部リンケージを使用して関数の依存呼び出しを許可する理由
:過度に制約され、過負荷解決ルールを簡素化します。その結果:
[C++11: 14.6.4.2/1]:
テンプレートパラメータに依存する関数呼び出しの場合、候補関数は、次の点を除いて、通常のルックアップルール(3.4.1、3.4.2、3.4.3)を使用して検出されます。
- 非修飾名ルックアップ(3.4.1)または修飾名ルックアップ(3.4.3)を使用したルックアップの一部では、テンプレート定義コンテキストからの関数宣言のみが検出されます。
- 関連する名前空間(3.4.2)を使用したルックアップの一部では、テンプレート定義コンテキストまたはテンプレートインスタンス化コンテキストのいずれかで見つかった関数宣言のみが見つかります。
[..]
(不足している「外部リンケージ付き」の資格を見つけます。)
問題#561(「依存名ルックアップの内部リンケージ関数」)、C ++ 11で制限が削除されることになった提案は、次のように尋ねます。
さらに、ルックアップから内部リンケージ関数を除外する必要が本当にありますか?ODRは、名前検索に別の問題を発生させることなく、このケースを処理するのに十分な許容範囲を実装に提供しませんか?
後の答えで:
グループのコンセンサスは、[..]内部リンケージ関数はルックアップによって検出される必要があるというものでした(ただし、過負荷解決によって選択された場合、エラーが発生する可能性があります)。
質問
制限の元々の実際的な理由は何でしたか?
元の標準的な表現は、外部リンケージを持つシンボルへのルックアップを制限するために邪魔になったので、1つあったに違いないようです。
「[内部リンケージ関数]が過負荷解決によって選択された場合、エラーが発生する可能性がある」というだけで、2000年代を通じて、これがどれほど重要であるかについて意見が変わりました。または、おそらく別のC ++ 11機能の別の場所での新しい表現の間接的な結果として、何か他の変更がありましたか?