テンプレートクラスの特別なメンバー関数(具体的には、コピー/ムーブコンストラクターとコピー/ムーブ代入演算子)はいつインスタンス化されますか?クラス自体がインスタンス化されるとすぐに、または必要なときにのみですか?
これは、次の状況で発生します。
template <class T, class U>
struct pair
{
T first;
U second;
pair() : first(), second() {}
pair(const pair&) = default;
};
struct S
{
S() {}
S(const S&) = delete;
S(S&&) = default;
};
int main()
{
pair<int, S> p;
}
Clangはこのコードのコンパイルを拒否し、次のエラーが発生します。
test.cpp:9:5: error: the parameter for this explicitly-defaulted copy constructor is const, but a member or base requires it to be
non-const
pair(const pair&) = default;
^
test.cpp:21:18: note: in instantiation of template class 'pair<int, S>' requested here
pair<int, S> p;
^
クラスがインスタンス化されるとすぐにコピーコンストラクターをインスタンス化しようとすることを示唆しています。
ただし、GCCはコードを正常にコンパイルするため、実際に必要な場合にのみコピーコンストラクターをインスタンス化しようとすることを示唆しています。
どのコンパイラの動作が正しいですか?
(代入演算子についても同様の不一致が見られます。)
更新pair
:これは、この例のコピーコンストラクターがedであるという事実と関係があります。これは、default
その定義を次のように変更した場合です。
pair(const pair& p) : first(p.first), second(p.second) {}
次に、コードはclangも渡します。