gpt4 book ai didi

c++ - 为什么isnan有歧义,如何避免?

转载 作者:可可西里 更新时间:2023-11-01 16:27:22 25 4
gpt4 key购买 nike

由于 isnan 可以是宏(在 C++98 中)或在命名空间 std 中定义的函数(在 C++11 中),一个明显的(和这个简单的例子说明了编写在这两种情况下都有效的代码的方式可能很幼稚

#include <cmath>

int main() {
double x = 0;
using namespace std;
isnan(x);
}

但是,编译它会在 GCC(使用 -std=c++11)和 Clang 中给出错误:

test.cc: In function ‘int main()’:
test.cc:6:10: error: call of overloaded ‘isnan(double&)’ is ambiguous
isnan(x);
^
test.cc:6:10: note: candidates are:
In file included from /usr/include/features.h:374:0,
from /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h:39,
from /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h:426,
from /usr/include/c++/4.8/cmath:41,
from test.cc:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:234:1: note: int isnan(double)
__MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
^
In file included from test.cc:1:0:
/usr/include/c++/4.8/cmath:626:3: note: constexpr bool std::isnan(long double)
isnan(long double __x)
^
/usr/include/c++/4.8/cmath:622:3: note: constexpr bool std::isnan(double)
isnan(double __x)
^
/usr/include/c++/4.8/cmath:618:3: note: constexpr bool std::isnan(float)
isnan(float __x)
^

为什么这在 C++11 中是模棱两可的,以及如何让它在 C++98 和 C++11 中工作,最好不要过多的条件编译?

最佳答案

这是错误报告中记录的 libstdc++ 错误 std functions conflicts with C functions when building with c++0x support (and using namespace std)具有与 OP 非常相似的复制样本:

#include <stdlib.h>
#include <cmath>
#include <stdio.h>

using namespace std;

int main(int argc, char** argv)
{
double number = 0;
if (isnan(number))
{
printf("Nan\n");
}
return 0;
}

其中一条评论说:

I don't think that's the problem, because libstdc++ has always declared the names in the global namespace even though it wasn't valid in C++03 - we haven't changed that for C++0x (all that happened is the standard was relaxed to reflect the reality of actual implementations)

此问题最终可能会得到修复,错误报告中提供的解决方案如下:

Qualify isnan explicitly, by calling either ::isnan or std::isnan

据我所知,使用 ::isnan 是可行的 pre C++11in C++11 .

当然这是一个 libstdc++ 特定的解决方案,它看起来在 libc++ 中也是有效的,但是如果你需要支持一个编译器,而这不起作用,你可能会有求助于使用 #if/#else

请注意,正如 M.M 所指出的,具有 isnan 标记的 constexpr 是不合格的,这是一个 known issue as well尽管它对这个特定问题没有贡献。

另请参阅相关错误报告:[C++11] call of overloaded ‘isnan’ is ambiguousRecognize builtins with bool return type .第二个讨论可能的 libstdc++ 解决方案。

更新

如果您想要 gcc/clang 解决方案,看起来它们都支持 __builtin_isnan,请参阅 gcc docs on builtins了解更多信息。另请参阅此 glibc bug report关于用内置函数替换 isnan 等人。

关于c++ - 为什么isnan有歧义,如何避免?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33770374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com