c ++模板参数不明确

时间:2012-01-25 08:31:57

标签: c++ templates compiler-errors type-mismatch

我正在尝试实现三个函数并且有很多错误,所有错误都具有相同的签名:

error C2782: 'T0 ColorBurn(T0,T0)' : template parameter 'T0' is ambiguous
error C2782: 'T1 ColorDodge(T1,T1)' : template parameter 'T1' is ambiguous

我犯了什么错误?
这是我的代码:

template <class T0>
T0 ColorBurn(T0 base, T0 blend)
{
    return (blend == 0.0) ? blend : std::max((1.0 - ((1.0 - base) / blend)), 0.0);
}
template <class T1>
T1 ColorDodge(T1 base, T1 blend)
{
    return (blend == 1.0) ? blend : std::min(base / (1.0 - blend), 1.0);
}
template <class T>
T BlendVividLightf(T base, T blend)
{
    return (blend < 0.5) ? ColorBurn(base, (2.0 * blend)) : ColorDodge(base, (2.0 * (blend - 0.5)));
}

调用BlendVividLightf的样本:

static pixel_t blend_vivid_light(pixel_t _p1, pixel_t _p2)
{
    pixel_t po;
    po.r = BlendVividLightf(_p1.r, _p2.r);
....
}
 pixel_t - is my struct for rgb values:
typedef struct  
{
    float r;
    float g;
    float b;
} pixel_t;

5 个答案:

答案 0 :(得分:9)

问题在于,当您调用ColorBurnColorDodge时,其中一个模板参数是浮点数,另一个是双精度数:

ColorBurn(base, (2.0 * blend))

这里,base是一个浮点数,表达式2.0 * blend是一个双精度数(因为2.0是一个双常数,所以整个表达式变为双精度。)

现在,编译器无法决定是为float还是为double实例化ColorBurn

要解决此问题,请将常量更改为单精度浮点常量(这可能是您想要的):

ColorBurn(base, (2.0f * blend))

同样适用于ColorDodge

请注意,如果您尝试将BlendVividLightf实例化为浮动以外的其他内容,您仍然会遇到问题 - 您的函数会以太多方式假设您正在处理浮点值,因此您将会如果您希望它们适用于其他参数类型,则必须引入一些类型转换。

答案 1 :(得分:3)

问题的原因是0.5double - 字面值,T0是浮点数。所以你传递的模板有两个不同类型的参数,因此编译器无法决定使用哪一个。有两种解决方案:

  1. 0.5更改为0.5f,使其成为float - 字面值。
  2. 为模板提供显式类型参数,如下所示:

    ColorBurn<float>(base, (2.0 * blend))
    

答案 2 :(得分:2)

也许您必须将(2.0 *混合)的结果转换为“T”并将其传递给ColorBurn ... 例如:

ColorBurn(base, static_cast<T>(2.0 * blend));

答案 3 :(得分:1)

我猜,问题是由于floatdouble不匹配造成的。您正在所有3个函数中强制(强制)同一类型template的{​​{1}}个参数。所以当你使用T0/T1/T调用函数时,它会有问题。请参阅此处的demo

这可以通过将float成员设为pixel_t而不是double来解决。

答案 4 :(得分:1)

你的问题在这一行:

ColorBurn(base, (2.0 * blend)) ...

这里的文字2.0将强制将第二个参数转换为double,但是由于第一个参数是其原始模板类型,并且在您的代码中稍后是float,编译器无法推断出您是否意思是致电ColorBurn<double>ColorBurn<float>(同样适用于此行后期致电ColorDodge)。

您可以通过以下方式之一修复错误:

  • 在函数调用中明确告诉编译器模板参数
  • 强制转换为第一个参数的两倍,例如... * 1.0
  • 将第二个参数中的双重文字更改为浮动文字,例如... * 2.0f
  • 为float和double编写专门化或单独的重载,并在上面进行适当的更改以确保两个参数都是相同的类型