0

一般的な戻り値の型を持つ関数の特殊化に関する簡単な質問だと思います。私の質問に答える別の投稿を見つけることができませんでしたが、おそらくその投稿は存在し、私はそれを理解していません (または見つけていません)。したがって、これが繰り返しではないことを願っていますが、
次のコードは私の問題を示しています

    class A {
        //...
        template<typename T> T func() { 
            cout << "Generic" << endl;
            T temp;
            return temp;
        }
    }

A.cpp

        //...
        template<> inline double A::func<double>() { 
            cout << "Double" << endl; 
            double d;
            return d;
        }

使用法:

int main() {
    A a;
    int var1 = a.func<int>();
    double var2 = a.func<double>();
}
 

コードからおそらく収集できることは、 doubleがテンプレート パラメーターである場合に汎用のfunc()関数を特殊化したいということです。ただし、実行すると次のように表示されます。

ジェネリック

ジェネリック

それ以外の:

ジェネリック

ダブル

ジェネリック バージョンが両方とも呼び出されるのはなぜですか? 希望する動作を取得するにはどうすればよいですか?

私の質問に対する答えが「あなたはおそらくこれをやりたくないでしょう」である場合に備えて、実際の状況についても簡単に説明します。コマンドライン引数 (文字列) をさまざまなデータ型 (int、double、bool など) に解析するクラスを書きたいだけです。明らかなアプローチの 1 つは、必要な型ごとに個別の関数を作成することです。別のアプローチとして、値を返す代わりに参照によって変数を渡し、型ごとに関数をオーバーロードすることもできます。

ただし、特殊な関数を使用すると、より拡張可能なコードになると考えていました。私の目標は、一般的なケースでエラーが発生するようにすることでした。「ターゲット タイプのパーサーをまだ実装していません」などのエラー メッセージが表示されますが、特殊なケースごとに適切な文字列からへのパーサーが実装されます。 . これにより、元のクラス ファイルを変更することなく、新しい型のパーサーを後で追加できるようになると考えました。これは、この引数パーサーをライブラリに構築しているためです。

わかりました、うまくいけばそれは理にかなっています。解決策よりも、コードが期待どおりに動作しない理由の説明に興味がありますが、どちらも高く評価されます!

4

1 に答える 1

3

関数の特殊化は .cpp ファイル内に「隠されている」ため、コンパイラはコンパイル時にそれを認識しませんmain(おそらく .cpp のみが含まれますA.h)。

これを修正するには、次のように特殊化を宣言しA.hます。

class A {
   // ...
};

template<> double A::func<double>();

をそのままにしておくとinline、おそらく関数の定義全体をヘッダーに移動することもできます。

于 2013-05-06T23:24:55.527 に答える