我正在尝试实现三个函数并且有很多错误,所有错误都具有相同的签名:
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;
答案 0 :(得分:9)
问题在于,当您调用ColorBurn
和ColorDodge
时,其中一个模板参数是浮点数,另一个是双精度数:
ColorBurn(base, (2.0 * blend))
这里,base
是一个浮点数,表达式2.0 * blend
是一个双精度数(因为2.0
是一个双常数,所以整个表达式变为双精度。)
现在,编译器无法决定是为float还是为double实例化ColorBurn
。
要解决此问题,请将常量更改为单精度浮点常量(这可能是您想要的):
ColorBurn(base, (2.0f * blend))
同样适用于ColorDodge
。
请注意,如果您尝试将BlendVividLightf
实例化为浮动以外的其他内容,您仍然会遇到问题 - 您的函数会以太多方式假设您正在处理浮点值,因此您将会如果您希望它们适用于其他参数类型,则必须引入一些类型转换。
答案 1 :(得分:3)
问题的原因是0.5
是double
- 字面值,T0
是浮点数。所以你传递的模板有两个不同类型的参数,因此编译器无法决定使用哪一个。有两种解决方案:
0.5
更改为0.5f
,使其成为float
- 字面值。为模板提供显式类型参数,如下所示:
ColorBurn<float>(base, (2.0 * blend))
答案 2 :(得分:2)
也许您必须将(2.0 *混合)的结果转换为“T”并将其传递给ColorBurn ... 例如:
ColorBurn(base, static_cast<T>(2.0 * blend));
答案 3 :(得分:1)
我猜,问题是由于float
和double
不匹配造成的。您正在所有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