2

次のコード

#include <stdio.h>
template <typename T, T v> class Tem
{
    T t;
    Tem()
    {
        t = v;
    }
};

typedef Tem<FILE*,NULL> TemFile;

MacOS X 上の Xcode によって .mm ファイル (Objective C++) にコンパイルされると、次のエラーがスローされます。

エラー: テンプレート引数 '0' を 'FILE*' に変換できませんでした。

どうしたの?問題のコードは、MSVC で正常にコンパイルされました。0 定数が何かへの有効なポインタではないのはいつですか? これは (バニラ C++ ではなく) Objective C++ のアーティファクトですか?

4

2 に答える 2

1

基準によると、あなたは運が悪いです。グローバルのアドレス以外のものへのポインタ引数を初期化する方法はありません。§14.3.2/1:

非型、非テンプレートのテンプレートパラメータのテンプレート引数は、次のいずれかである必要があります。

  • 積分定数-積分型または列挙型の式。また
  • 非型テンプレートパラメータの名前。また
  • 関数テンプレートおよび関数テンプレートIDを含むが、非静的クラスメンバーを除く、外部リンケージを持つオブジェクトまたは関数のアドレス。&id-expressionとして表されます 。名前が関数または配列を参照する場合、または対応するtemplate-parameterは参照です。また
  • 5.3.1で説明されているように表現されたメンバーへのポインタ。

§14.3.2/5:

  • オブジェクトへの型ポインターの非型テンプレートパラメーターの場合、資格変換(4.4)および配列からポインターへの変換(4.2)が適用されます。[注:特に、nullポインター変換(4.10)も派生からベースへの変換(4.10)も適用されません。0は、整数型の非型テンプレートパラメータの有効なテンプレート引数ですが、ポインタ型の非型テンプレートパラメータの有効なテンプレート引数ではありません。]

ただし、Comeauはこの無効な回避策を受け入れます。

typedef Tem<FILE*, (FILE *) NULL > TemFile;

そして、このコードはコンプライアンスの可能性がわずかです。標準が、欠落している引数の代わりにデフォルトの式が逐語的に使用されると具体的に述べている場所を見つけることができず、一致する既知の欠陥を見つけることができません。誰かが参照を持っていますか?

#include <stdio.h>
template <typename T, T *v = (T*) 0> class Tem
{
    T t;
    Tem()
    {
        t = v;
    }
};

typedef Tem<FILE> TemFile;

移植性を高めるために、偽FILE FILE_NULL;の、passを作成し&FILE_NULL、ゼロではなくそれを使用してポインターが等しいかどうかをテストすることを検討してください。

于 2010-03-30T22:20:18.730 に答える
-1

このようなことを試しましたか?

typedef Tem<FILE*,((FILE*)NULL)> TemFile;

おそらく、NULL の型を把握しようとしているのでしょう。

于 2010-03-30T21:51:32.323 に答える