3

次のような明示的なインスタンス化の助けを借りて、cpp ファイルに実装されている関数テンプレートがあるとします。

関数.h

template<typename T> void function(T val);

関数.cpp

#include "function.h"

template<typename T> void function(T val) { /* do something */ }

template void function<double>(double val);

次のように、 function.hを含むメイン ファイルで関数を呼び出すことができるようになりました。

double val = 1.0;

function(val);

さらに、次のように実装されたクラスがあると仮定します。

data.h

class Data
    {
    private:
        double mVal;

    public:
        Data(double val) { mVal = val; }

        operator double () { return mVal; }
    };

次のコードでは、リンカー エラー LNK2019: unresolved external (Visual Studio 2010) が発生します。

Data a(1.0);

function(a);

次の式のいずれかを使用して to function()を指定できます。

function<double>(a);
function(double(a));
...

しかし、 function(a)を単に呼び出すことができないのはなぜですか? function()をデータ型で明示的にインスタンス化せずにそれを達成するための他の解決策はありますか?

4

2 に答える 2

6

単に呼び出すことができないのはなぜfunction(a)ですか?

です。あなたはそれを呼んでいます。functionただし、次のように宣言されていることを覚えておいてください。

template<typename T> void function(T val);

したがって、テンプレート演繹は を推測しfunction<Data>ます。テンプレート演繹は、コードの他の場所に定義しかないことを認識していませんfunction<double>- 演繹を行うだけです。function<Data>定義がないため、リンクに失敗します。

私の意見では、明示的なキャストを自分で実行すること(またはのいずれfunction<double>(a)function(static_cast<double>(a)))が最善の解決策です。明示的でいいです。さらに、実際にサポートするすべてのオーバーロードを使用して別の関数を作成し、関数テンプレートに転送することもできます。

void fwd_function(double v) { function(v); }
void fwd_function(foo v) { function(v); }
void fwd_function(bar v) { function(v); }

fwd_function(a); // now we call function<double> because fwd_function(double )
                 // is the what we're actually calling
于 2016-05-19T16:55:34.750 に答える