【问题标题】:Default argument of type float = gibberishfloat 类型的默认参数 = 胡言乱语
【发布时间】:2011-09-25 20:51:36
【问题描述】:

我在使用 float 类型的默认参数时遇到了一些问题:

#include <wchar.h>
#include <iostream>

template<typename T>
void fun(T t = 1e-05);

template<typename T> inline
void fun(T t)
{
    std::cout << t << std::endl;
}

int wmain(int argc, wchar_t* argv[])
{
    fun<float>();

    _getwch();
    return 0;
}

它打印 -1.36867e-033 而不是等价的 1e-05。这是怎么回事?

我正在使用 VC++10。

EDIT1:

感谢大家的回复。 但是在以下情况下强制转换默认参数不起作用:

template<typename T>
void fun(T t = static_cast<T>(1e-05));

template<typename T> inline
void fun(T t)
{
    std::wcout << t << std::endl;
}

int wmain(int argc, wchar_t* argv[])
{
    fun<double>();
    fun<float>();

    _getwch();
    return 0;
}

所以这绝对是一个错误并且值得报告?

EDIT2:

Reported this issue to Microsoft

【问题讨论】:

  • 您期望编译器发出从 double 到 float 的转换。它没有。使用“1e-5f”修复它。使用 connect.microsoft.com 报告此问题。
  • 也许您的平台上需要wcout
  • @Hans:微妙。我正要建议fun(T t = T(1e-05)),但认为这没有必要……顺便说一句,它在 GCC 4.6 上运行良好。
  • @Kerrek:wcout 与这里有什么关系?您为什么希望这样可以解决问题?
  • 嗯,这个解决方法会使编译器跳闸:template &lt;typename T&gt; struct def_arg { static const T value; }; template &lt;typename T&gt; const T default_arg&lt;T&gt;::value = T(1e-05); template&lt;typename T&gt; void fun(T t = default_arg&lt;T&gt;::value); template&lt;typename T&gt; inline void fun(T t) { std::cout &lt;&lt; t &lt;&lt; std::endl; }

标签: c++ visual-studio visual-studio-2010 templates visual-c++


【解决方案1】:

似乎是默认模板参数以及双精度和浮点数之间的转换存在问题。如果您不使用模板,则不会出现此问题。

在该默认模板参数的末尾添加一个“f”,以便将值视为“float”而不是 double。这似乎可以解决它。

template<typename T>
void fun(T t = 1e-05f);

但是在应用上述修复后,如果你声明这个

fun<double>()

你得到一个等效的错误。因此,对浮点数和双精度数都有效的更好的解决方法是使用强制转换,如下所示:

template<typename T>
void fun(T t = (T)(1e-05));

至于这是编译器错误还是“未定义的行为”,我会让编译器大师插话。

【讨论】:

  • 不错的答案,它为早期的 cmets 添加了一些额外内容,但仍然 -1 甚至不承认 Hans 和 Kerrek 的见解......
  • @Tony:这个答案完全是我自己的。在我写下答案并验证解决方案时,我看不到 cmets。 S.O. 将在您编写自己的答案时通知您其他提交的答案。但是,直到您发布之后,您才能看到新的 cmets。是的,当人们窃取我的答案并获得荣誉时,我讨厌它。但这是一个诚实的错误。
  • 好吧,那是我的错误......我会“-1 到 +1”,但除非您的答案已编辑,否则不能。并且道歉……!干杯。
  • 如果您删除单独的声明并将参数移动到定义中,也不会出现此问题。
  • @MSalters:是的,我也注意到了。
猜你喜欢
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 2018-12-21
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多