2012-12-19 102 views
5

好吧,我读throught颇有些“不能推导出模板参数”问题,但没有一个似乎符合我的情况 - 或者我不明白的答案...嵌套模板推导模板参数失败

one,我感觉朝着正确的方向发展,但是我没能解决我的问题。

在我的头中的精简代码如下所示:

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 

的当我将两个struct s作为移出class时也会发生错误建议。

+1

实例化代码和错误消息是完全无关的。这个错误提到'StaticCast ',但是你的实例代码中没有任何地方。 – Xeo

+0

http://liveworkspace.org/code/4psoUf$0编译得很好......你的代码(在更正之前)是不可编译的。 – ForEveR

+0

@Xeo:StaticCast从底部开始使用3行。 – primfaktor

回答

4

编译器错误对指示实际问题没有多大帮助。

实际的问题是,按值传递UnaryFunction<Tin, T>Init功能(和一个构造函数),但在一个抽象类UnaryFunction<>结果所有实例(不能按值传递)。 的简单的解决方案是使用用于UnaryFunction通过按引用,以便mapper指的是在传递的实际对象

在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,则在功能主体中使用它时将被诊断。

+0

'Tmapper'模板参数可以*和*使生活更轻松。非常感谢! – primfaktor