显式实例化
这是由这篇文章(第5页)激发
template<class T>
T const &f(T const &a, T const &b){
return (a > b ? a : b);
}
template int const &f<int>(int const &, int const &);
int main(){
int x = 0, y = 0;
short s = 0;
f(x, y); // OK
f(x, s); // Is this call well-formed?
}
的'f(x, s)'
格式良好?我假设由于函数模板 'f'
已显式实例化,因此将应用标准转换,因此 'short s'
将转换为 'int'< /code> 匹配对显式特化
'f
的调用。但这似乎格式不正确?
标准的哪一部分讨论了这种情况下的适用规则?
This was motivated by this article (page 5)
template<class T>
T const &f(T const &a, T const &b){
return (a > b ? a : b);
}
template int const &f<int>(int const &, int const &);
int main(){
int x = 0, y = 0;
short s = 0;
f(x, y); // OK
f(x, s); // Is this call well-formed?
}
Is the call 'f(x, s)'
well-formed? I assumed that since the function template 'f'
is explicitly instantiated, standard conversions would be applied and hence 'short s'
would be converted to 'int'
to match the call to the explicit specialization 'f<int>'
. But it appears that this is ill-formed?
Which part of the Standard talks about the applicable rules in this context?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,调用
f(x, s)
的格式不正确。由于您没有明确声明要使用的专业化,编译器会使用参数推导来尝试实例化函数模板;这会失败,因为x
和s
具有不同的类型,因此T
不明确。适用的规则在 13.3.1 中的重载解析过程规范中:
14.8.3/1 也相关:
函数模板已为
T = int
显式实例化,但编译器不知道应该使用此实例化,直到执行模板参数推导以确定T
应该做什么是。No, the call
f(x, s)
is not well-formed. Since you do not explicitly state the specialization to be used, the compiler uses argument deduction to attempt to instantiate the function template; this fails becausex
ands
have different types soT
is ambiguous.The applicable rule is in the specification of the overload resolution process in 13.3.1:
14.8.3/1 is also relevant:
The function template is explicitly instantiated for
T = int
, but the compiler doesn't know that it should use this instantiation until after it performs template argument deduction to determine whatT
should be.调用
f(x, s)
在语法上是正确的,但编译器将无法从中推导出模板参数T
,因为它可能是一个int
或short
(因为第一个和第二个参数)。实例化模板没有帮助,它仅指示编译器编译该专业化并将其添加到生成的目标文件中。如果您希望调用自动将
s
转换为int
,请使用f(x, s)
。The call
f(x, s)
is syntactically well-formed, but the compiler will not be able to deduce the template parameterT
from it because is could aint
or ashort
(because of the first and second arguments). Instantiating the template does not help, that only indicates the compiler to compile that specialization and add it to the generated object file.If you want the call to cast
s
to aint
automatically, usef<int>(x, s)
.显式实例化的专业化没有任何更高的优先级或优惠待遇。从实例化的角度来看,它只是完整地存在。对图书馆有用。
编译器根本无法确定要转换哪个参数,并且会像没有额外声明一样陷入困境。
顺便说一句,如果您返回对已转换参数的引用,则一旦临时过期,它将悬空。如果参数是对不同类型的引用,则无法正确形成返回值。
这是我更新的
min
:An explicitly instantiated specialization doesn't have any higher priority or preferential treatment. It simply exists in its entirety from the point of instantiation. Useful for libraries.
The compiler simply can't figure out which argument to convert, and gets stuck just as it would without the extra declaration.
By the way, if you return it a reference to an argument which was converted, it will be dangling once the temporary expires. If the arguments are references to different types, there is no way to properly form the return value.
Here is my updated
min
: