为什么将double转换为看似任何原语的const引用?

R_K*_*app 4 c++ language-lawyer reference-binding

考虑以下代码:

#include <iostream>

float func(char const & val1, unsigned int const & val2)
{
    return val1 + val2;
}

int main() {
    double test1 = 0.2;
    double test2 = 0.3;

    std::cout << func(test1, test2) << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

尽管我将a传递double给采用const引用小于a的类型的函数double(在我的系统上sizeof(double) == 8,while sizeof(unsigned int) == 4sizeof(char) == 1按定义),但该函数仍可编译和运行。如果引用不是const,则编译失败(例如, float func(char & val1, unsigned int & val2)而不是当前定义),并显示以下错误:

不能将'char&'类型的非常量左值引用绑定到'char'类型的右值

在Godbolt上使用GCC,Clang,ICC和MSVC进行测试时,我得到的行为完全相同,因此它看起来是标准的。导致该接受的const-references是什么呢,而引用不是?另外,我曾经使用过-Wall -pedantic-为什么我没有收到有关转换范围缩小的警告?当函数按值传递而不是按引用传递时...

Bat*_*eba 8

这确实是标准的。

test1test2转换为匿名临时 类型charunsigned类型,const函数中的引用对其进行适当的绑定。如果将编译器设置为警告您缩小转换范围(例如-Wconversion),它将输出一条消息。

如果函数参数是非const引用,则这些绑定是不可能的,并且在这种情况下,编译器将正确发出诊断信息。

一种解决方法是delete更好的重载匹配:

float func(double, double) = delete;
Run Code Online (Sandbox Code Playgroud)

  • 我真的希望gcc拥有“-绝对一切,如果我抱怨我是白痴”选项。`-Wextra`会给您`-Wconversion`吗? (6认同)
  • @Omnifarious:如果我能够加入gcc开发团队(Heaven禁止!),那将是我的第一个项目。 (2认同)