c++模板参数不明确

c++ template parameter is ambiguous

本文关键字:不明确 参数 c++      更新时间:2023-10-16

我试图实现三个函数,但有很多错误,所有这些错误都有相同的签名:

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;

问题是,当您调用ColorBurnColorDodge时,其中一个模板参数是float,另一个是double:

ColorBurn(base, (2.0 * blend))

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

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

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

ColorBurn(base, (2.0f * blend))

对于CCD_ 7也是类似的。

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

问题的原因是0.5是一个double文本,而T0是一个浮点。因此,您要向模板传递两个不同类型的参数,因此编译器无法决定使用哪一个。有两种解决方案:

  1. 0.5更改为0.5f,使其成为float文字
  2. 为模板提供显式的类型参数,例如:

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

也许您必须将(2.0*blend)的结果强制转换为"T"并将其传递给ColorBurn。。。例如:

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

我可以猜测,问题是由于floatdouble不匹配造成的。在所有3个函数中,您正在生成(强制)相同类型T0/T1/T的两个template参数。因此,当您使用float调用函数时,它将出现问题。请在此处查看演示。

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

您的问题在这一行:

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

在这里,literal 2.0将强制将第二个参数转换为double,但是,由于第一个参数是它的原始模板类型,并且在稍后的代码中它是float,编译器无法推断您是要调用ColorBurn<double>还是ColorBurn<float>(这一行稍后对ColorDodge的调用也是如此)。

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

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