次のコード例を考えると
struct S;
template<typename>
class C
{
public:
void f(bool b)
{
if (b)
g();
}
void g()
{
S{};
}
};
int main()
{
C<int>{}.f(false);
}
GCC は以下を正しく報告します。
example.cpp: In instantiation of 'void C< <template-parameter-1-1> >::g() [with <template-parameter-1-1> = int]':
10 : required from 'void C< <template-parameter-1-1> >::f(bool) [with <template-parameter-1-1> = int]'
21 : required from here
15 : error: invalid use of incomplete type 'struct S'
私の質問は次のとおりです。この保証された動作は、標準またはその他のドキュメントで何らかの決定を下していますか?
私の質問についてより正確に言うと:
C
はテンプレート クラスであり、メンバーf()
がg()
参照されている場合にのみインスタンス化されます。f()
で参照されていmain()
ます。参照しない場合g()
(内部的に不完全な型を使用しようとします)、コードはコンパイルされます。しかしg()
、内部の if-branch 内で参照されていますf()
。このブランチは決定論的に実行されることはありません。そのため、コンパイラはこのデッド コード ブランチを無視/削除する可能性があり、インスタンス化を回避できますg()
(これにより、不完全な型を使用しようとするエラーが発生します)。ただし、これは発生していません (少なくとも私が試したコンパイラでは)。
これを許可すると、コンパイラの最適化設定を調整するだけで違法なコードが合法的なコードに変わることを理解していますが、それでも私の質問は、このコード例がいくつかのルール (最適化とテンプレート パスの順序など) によって失敗することが保証されているかどうかです。どこかで読めます。
洞察をありがとう。