パスワードを忘れた? アカウント作成
488608 journal

Yoh2の日記: [C/C++規格: 3] クラステンプレートのメンバ関数明示的特殊化の具現

日記 by Yoh2

むう。タイトルが長い。つか「の」多すぎ。

私がよく見に言っているプログラミング関係の掲示板で、クラステンプレートの特殊化&明示的インスタンス化というトピックが立ったことがあった。
内容は、クラステンプレートのメンバ関数の明示的特殊化を別ファイルで定義したいけど、リンクエラーが発生してしまう。どうしたらリンクエラーを解消することができるか、というもの。
当時、「その別ファイルで明示的特殊化すればいいんでない?」と提案し、それでうまくいったと報告を受けたんだけど、つい先日、コンパイラを変えたらエラーになったとの報告を受けた。
改めて調べてみると、明示的特殊化と明示的具現を同時に行うのはNGらしい。

とりあえず、その明示的具現を行っている文をコメントアウトした状態でビルド(以前に問題が起こった方法)。
当然リンクエラーになるだろうと思っていたけれど、いろいろなコンパイラで調べてみるとマチマチ。

私の試した範囲では、別ファイルに記述したクラステンプレートのメンバ関数の定義を

具現する
gcc-4.1.2, Intel C/C++ Compiler for Linux 8.1
具現しない(リンクエラー)
VC++2005 SP1
具現しない(汎用のA::func()をリンク)
Ditital Mars C/C++ 8.42n
そもそもコンパイルが通らない
Borland C/C++ 5.5.1

このうちどれが正しいのか(未規定だったり処理系定義だったりで複数もあり?)、またはプログラムが間違いなのか見極めようと規格書 (JIS X 3014:2003) を漁ってみた。
# 下ふたつは問題外だろうなぁと思ってたり。

14。7。1 暗黙の具現化 - 2

関数テンプレートの特殊化は,それが,既に明示的に具現されているか又は明示的に特殊化されている場合を除き,その関数定義が要求される文脈で用いられたときに,暗黙に具現される。

ふむふむ。明示的に特殊化された関数テンプレートは、関数定義が要求されるのとは別のタイミングで具現されるわけか。

14。7。1 暗黙の具現化 - 9

クラステンプレートの,関数テンプレート,メンバテンプレート,非仮想メンバ関数,メンバクラス 又は 静的データメンバの具現化が要求されない場合,それらは暗黙に具現してはならない。

で、勝手に具現してもダメ、と。
なら、明示的に特殊化された関数テンプレートが具現されるタイミングが、関数定義が要求される文脈で用いられたとき以外にあるはず。と、探してみたけれど、今のところ見付からず。
少なくとも、「14.7.3 明示的な特殊化」には書かれていないみたい。
明示的な特殊化は同時に具現も行う、といった類の記述でもあればすっきり解決なんだけどなぁ。
このままだと、別ファイルに明示的特殊化版を定義するどころか、同じファイルで定義しても明示的特殊化版を使えない(具現されない)ということに。
そんなバカなことはあり得ないはずなんだけど。むぅ、何を見落としてるんだろ。

あー、混乱してきた。ある程度整理したら掲示板に書き込もうかと思ったけど、整理できるのはいつになるかなぁ。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

物事のやり方は一つではない -- Perlな人

読み込み中...