【问题标题】:Deducing template argument for nested template fails为嵌套模板推导模板参数失败
【发布时间】:2012-12-06 14:05:37
【问题描述】:

好的,我阅读了很多“无法推断模板参数”的问题,但似乎没有一个与我的情况相符——或者我不明白答案……

我觉得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

当我按照this answer 的建议将两个structs 移出class 时也会发生错误。

【问题讨论】:

  • 实例化代码和错误信息完全不相关。该错误涉及StaticCast&lt;Tin,Tout&gt;,但您的实例化代码中没有任何内容。
  • liveworkspace.org/code/4psoUf$0 编译良好...您的代码(更正前)不可编译。
  • @Xeo:StaticCast 从底部开始使用 3 行。
  • 哦,是的,nvm,你有一个额外的Init 函数......我不知何故把它和构造函数混在一起了。
  • @primfaktor 这会产生差异,因为无法创建抽象类的对象。 UnaryFunction 映射器 - 非法。无论如何,gcc 编译得很好。

标签: c++ templates compiler-errors


【解决方案1】:

编译器错误对指示实际问题的帮助不大。

实际的问题是您将 UnaryFunction&lt;Tin, T&gt; 按值传递给您的 Init 函数(以及其中一个构造函数),但 UnaryFunction&lt;&gt; 的所有实例化都会产生一个抽象类(不能按值传递) . 简单的解决方案是对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&lt;&gt; 基类了。如果传递了不兼容的mapper,在函数体中使用时会被诊断出来。

【讨论】:

  • Tmapper 模板参数有效并且让生活更轻松。非常感谢!
猜你喜欢
  • 2022-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
  • 1970-01-01
  • 2012-02-07
  • 2012-10-26
相关资源
最近更新 更多