我认为您可能会对右值和 const 限定符感到困惑。 function
返回 int 类型的非 const 右值临时值,因此编译器将 T 推导出为 int,因为它应该。正如您所指出的,您可以将临时绑定到 const ref (c++03 12.2/5),但编译器不会添加 cv 限定符来使函数调用格式良好。由于您无法控制模板功能,因此有两种方法(除了您发布的解决方案)。
(1) 显式模板参数:function2<const int>(function())
(2) cv 合格回报:const int function();
这两种解决方案都形成良好。(1)似乎是更好的解决方案,恕我直言,因为(2)是非常规和愚蠢的。
编辑:实际上,推导的类型可以比 ref 模板参数的参数更具 cv 限定,但前提是类型推导否则会失败(c++03 14.8.2.1/3)。在这种情况下,类型推导不会失败,但会导致格式错误的函数调用(SFINAE 不适用,因为模板函数特化本身没有格式错误)。
如果模板作者的意图是不修改参数,则应将其声明为 const 引用参数,因此这可能是模板库中的错误,或者它可能会修改参数,在这种情况下,您所做的将在函数尝试修改参数时失败。
编辑:正如 FredOverflow 指出的那样,非类右值始终是标准 3.10/9 不合格的 cv。所以(2)在 gcc 4.3 下工作,实际上是一个编译器错误(gcc <4.5,根据 FredOverflow)。