如何在 g++ 4.3.4 中诊断对 sqrt(int&) 的不明确调用

How to diagnose ambiguous call to sqrt(int&) in g++ 4.3.4

本文关键字:int sqrt 不明确 调用 g++ 诊断      更新时间:2023-10-16

我的代码如下:

#include <cmath>
#include <iostream>
float foo(float f) {
    std::cout << "floatn";
    return f;
}
double foo(double d) {
    std::cout << "doublen";
    return d;
}
int main() {
    int i = 16;
//  foo(i); // ambiguous call, of course
    return (int) std::sqrt(i);
}

即使使用-pedantic -std=c++98 -Wall -Wextra,最后一行中的调用也不会报告模棱两可,但它不一定在其他编译器中根本不起作用,原因与foo(i)不工作的原因相同。

GCC 将以下内容添加到命名空间std

template<typename _Tp>
    inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
                                       double>::__type
    sqrt(_Tp __x)
    { return __builtin_sqrt(__x); }

也就是说,它为所有整数类型 X 添加inline double sqrt(X)

我很感激 g++ 尽最大努力帮助我,但是是否有任何(合法)方法可以让它诊断我代码中的错误?

[编辑:我正在使用gcc 4.3.4,但如果其他版本的gcc可以诊断它,那么我也对这一事实感兴趣!

GCC 添加的这个"有用"标准库在 C++03 中不符合,根据
[lib.global.functions]/2

对全局函数签名 [在标准库定义中描述] 的调用的行为与实现不声明其他全局函数签名的行为相同。

这意味着实现(gcc)不允许添加额外的重载(有用与否),只要它们影响程序的可观察行为。

你想要FDIS的报价吗?

26.8的最后一段:

此外,还应有额外的超载,足以确保:

  1. 如果对应于double参数的任何参数的类型为 long double ,则对应于double参数的所有参数都将有效地转换为 long double

  2. 否则,如果对应于double参数的任何参数具有类型 double 或整数类型,则对应于double参数的所有参数都将有效地转换为 double

  3. 否则,对应于double参数的所有参数都将有效地转换为 float

在这种情况下,必须适用第 2 点。