5

OK、「テンプレート引数を推測できませんでした」という質問をかなり読みましたが、私のケースに一致するものはないようです — または答えがわかりません…</p>

正しい方向に進んでいると感じるものがありますが、問題の解決策を抽出できませんでした。

ヘッダーの簡略化されたコードは次のようになります。

template<typename T>
class TemplateProblem
{
public:
    // Do I really need this or did I miss something from the STL?
    template<typename Tin, typename Tout>
    struct UnaryFunction : public std::unary_function<Tin, Tout>
    {
        virtual Tout operator()(Tin input) = 0;
    };

    template<typename Tin, typename Tout>
    struct StaticCast : public UnaryFunction<Tin, Tout>
    {
        virtual Tout operator()(Tin input)
        {
            return static_cast<Tout>(input);
        }
    };

private:
    T * const _data;
    T const _bias;

    template<typename Tin>
    void Init(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias);

public:
    template<typename Tin>
    TemplateProblem(Tin * data, int length, Tin bias = Tin());

    template<typename Tin>
    TemplateProblem(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias = T());
};

template<typename T>
template<typename Tin>
void TemplateProblem<T>::Init(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias)
{
    T mappedBias = mapper(bias);
    for (int i = 0; i < length; i++)
    {
        _data[i] = data[i] + mappedBias;
    }
}

template<typename T>
template<typename Tin>
TemplateProblem<T>::TemplateProblem(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias = T())
    : _data(new T[length]), _bias(bias)
{
    Init(data, length, mapper, bias);
}

template<typename T>
template<typename Tin>
TemplateProblem<T>::TemplateProblem(Tin * data, int length, Tin bias = T())
    : _data(new T[length]), _bias(bias)
{
    StaticCast<Tin, T> cast;
    Init(data, length, cast, bias);
}

次のようにインスタンス化します。

unsigned char pixels[] = {23, 42, 65, 97};
TemplateProblem<int> tp(pixels, 4);

VS2012 から、次のメッセージが表示されます。

Error   1   error C2784: 'void TemplateProblem<T>::Init(Tin *,int,TemplateProblem<T>::UnaryFunction<Tin,T>,Tin)' : could not deduce template argument for 'TemplateProblem<T>::UnaryFunction<Tin,T>' from 'TemplateProblem<T>::StaticCast<Tin,Tout>'    ...\templateproblem.h   62  1   TemplateProblem
Error   2   error C2893: Failed to specialize function template 'void TemplateProblem<T>::Init(Tin *,int,TemplateProblem<T>::UnaryFunction<Tin,T>,Tin)' ...\templateproblem.h   62  1   TemplateProblem

この回答が示唆するように、2つstructの s を の外に移動すると、エラーも発生します。class

4

1 に答える 1

4

コンパイラ エラーは、実際の問題を示す上ではあまり役に立ちません。

実際の問題は、関数 (およびコンストラクターの 1 つ) にUnaryFunction<Tin, T>値で渡すことですが、すべてのインスタンス化が抽象クラスになります (値で渡すことはできません)。簡単な解決策は、参照渡しを使用して、渡された実際のオブジェクトを参照することです。InitUnaryFunction<>UnaryFunctionmapper

ファンクターを渡すための STL での一般的な解決策は、次のように別のテンプレート引数を使用することです。

template<typename T>
template<typename Tin, Tmapper>
void TemplateProblem<T>::Init(Tin * data, int length, Tmapper mapper, Tin bias)
{
    T mappedBias = mapper(bias);
    for (int i = 0; i < length; i++)
    {
        _data[i] = data[i] + mappedBias;
    }
}

UnaryFunctionL<>次に、基本クラスは必要ありません。非互換mapperが渡された場合、これは関数の本体で使用されたときに診断されます。

于 2012-12-19T09:32:33.020 に答える