8

我的代码如下:

#include <cmath>
#include <iostream>

float foo(float f) {
    std::cout << "float\n";
    return f;
}
double foo(double d) {
    std::cout << "double\n";
    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); }

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

我感谢 g++ 尽最大努力帮助我,但是有什么(合法的)方法可以让它诊断出我的代码中的错误吗?

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

4

2 回答 2

2

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

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

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

于 2011-05-19T09:48:18.373 回答
2

您想要 FDIS 的报价单吗?

26.8的最后一段:

此外,应有足够的额外过载以确保:

  1. 如果任何与形参对应的double实参具有类型long double,则与形参对应的所有实double参都被有效地强制转换为long double

  2. 否则,如果与形参对应的任何实double参具有类型double或整数类型,则与形参对应的所有实double参都被有效地强制转换为double.

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

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

于 2011-05-19T09:31:40.400 回答