[[deprecated]]の解説を書くためにCC++14の文面を解釈していて、以下のような疑問を持った。
§ 7.6.5 paragraph 2
The attribute may be applied to the declaration of a class, a typedef-name, a variable, a non-static data member, a function, a namespace, an enumeration, an enumerator, or a template specialization.
テンプレートの特殊化(template specialization)という用語の使用がとても気になる。
何故ならば、テンプレートの特殊化の宣言というものは、明示的なテンプレートの特殊化ぐらいしか思いつかないからだ。通常のテンプレートの特殊化は、暗黙のテンプレートの実体化された結果であり、宣言は存在しない。プライマリーテンプレートの宣言はテンプレートの宣言であり、テンプレートの特殊化の宣言ではない。
すると、テンプレート宣言にはdeprecated属性が使えないのだろうか。
「テンプレートの特殊化」という用語を使用することのもうひとつの問題は、template-idに限定してしまうということだ。template-nameはテンプレートの特殊化ではない。
// テンプレートの特殊化の宣言ではないが
template < typename T >
class [[deprecated]] A { } ;
template < template < typename > typename T >
class B { } ;
// 警告
// template-idはテンプレートの特殊化
A<int> ;
// 警告なし
// template-nameはテンプレートの特殊化ではない
B<A> b ;
現在のClangの実装は、正しく(?)A<int>とB<A>のどちらとも警告を出さない。GCCはどちらとも警告を出す。
こういう細かい文面解釈の問題が気になってしまってなかなかC++14解説の執筆が進まない。
ドワンゴ広告
この記事はドワンゴ勤務中に書いた。
ドワンゴは本物のC++プログラマーを募集しています。
CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0
2大コンパイラで挙動が違うということは、一応両方に報告するべきでしょうか??
ReplyDelete自分は英語ができませんが。