0

以下函数模板尝试从输入的值中计算最大值。当我将 FT 与单一数据类型一起使用时,它工作得很好,但在与两种不同的数据类型一起使用时会显示警告。

功能如下:

template<typename T,typename U>
const T& maxVal(const T& var1,const U& var2)
{
if(var1<var2)
    return var1;
else
    return var2;
}

用户功能( main )如下:-

int main(void)
{
  int var1 = 10;
  double var2 = 20.10;
  cout<<maxVal(10,20.10)<<endl;   // warning displayed " returning reference to temporary"
   cout<<maxVal(var1,var2)<<endl; // warning still persists in this case
  return 0;
}

当我删除U数据类型并将其替换为 时T,程序运行顺利。为什么会这样?

4

4 回答 4

1

如果 T 是 int 而 U 是 double,那么当 U 是最大值时,您将尝试将 double 引用作为 int 引用返回。您不能这样做,因此编译器将首先执行从 double 到 int 的类型转换,从而生成一个临时变量,然后它将其作为引用返回,该引用将在函数返回后立即超出范围。

如果您将其更改为返回 T 而不是 T& 那么它应该可以工作。

通过工作,我的意思是它不会给你一个关于临时变量的警告。但我怀疑它也能达到你的预期。

如果您的双精度值是最大值并以 int 形式返回,那么您将不会返回您输入的相同值。相反,您将获得一个表示双精度值的整数值。在您的示例中,它将输出 20 而不是 20.10。

您确实需要使用宏来执行您在示例中似乎想要执行的操作。

#define maxValue(a1,a2) \
   (a1 < a2 ? a2 : a1)
于 2013-08-14T15:09:46.760 回答
1
template<typename T>
const T& maxVal(const T& var1,const T& var2)

如果您使用maxVal(10,20.10)其中一个,则会隐式转换为另一个。这里 double 被强制转换为 int

template<typename T,typename U>
const T& maxVal(const T& var1,const U& var2)

有了这个实现,你总是会返回T,所以如果var2是最大值,它会被强制转换为T

于 2013-08-14T15:00:04.633 回答
0

您实际上可能想要这样的东西:

template<typename T, typename U>
auto maxVal(const T& var1, const U& var2) -> decltype(var1<var2?var2:var1)
{
    return var1<var2 ? var2:var1;
}

但是,运行时变量不能在编译时扣除。像这样的代码只能在编译时工作,因为它的返回类型必须在编译时确定。

编辑:

令我惊讶的是,这段代码实际上适用于 GCC 4.8,甚至用于运行时变量。希望有人能解释一下这个魔法吗?

编辑2:

对不起这是我的错。请参阅@Sebastian Redl 下面的评论以获取解释。

于 2013-08-14T15:17:17.837 回答
-1

警告“返回对临时变量的引用”是指您返回对临时变量的引用(函数内部的变量,当函数终止时超出范围)。

你为什么要返回一个 const 引用?

template<typename T,typename U>
const T maxVal(const T& var1,const U& var2)
{
if(var1<var2)
    return var1;
else
    return var2;
}
于 2013-08-14T15:06:33.427 回答