什么时候出现“需要重载定义”错误?

时间:2019-03-28 18:01:58

标签: c++ overloading

以这个简单的例子为例:

#include <iostream>

using namespace std;

void Display(char a, char b, char c)
{
   cout << a << " " << b << " " << c << endl;
}

int main()
{
   Display(2, 3, 4); // Why no syntax error?
   Display(2.0, 3.0, 4.0); // Also no error? O.o
   Display('a', 'b', 'c');

   system("pause");
   return 0;
}

我期望在前两个Display()调用中出现错误,即:

  

未找到需要(int,int,int)的Display()定义。

     

未找到需要(双精度,双精度,双精度)的Display()定义。

然后我将不得不在其中重载Display()并添加接受正确参数的参数。

那么在什么情况下我实际上会收到语法错误?为什么在这种情况下我没有收到错误消息?

3 个答案:

答案 0 :(得分:4)

由于Standard conversions/Integral convesionsint可以转换为char

  

整数类型的prvalue可以转换为另一种整数类型的prvalue。可以将无作用域枚举类型的prvalue转换为整数类型的prvalue。

整数类型的定义可以在Basic concepts/Fundamental types看到。

  

类型boolcharchar16_tchar32_twchar_t和有符号和无符号整数类型统称为整数类型。整数类型的同义词是整数类型


由于Standard conversions/Floating-integral conversionsdouble也可以转换为char

  

浮点类型的prvalue可以转换为整数类型的prvalue。转换被截断;也就是说,小数部分将被丢弃。

答案 1 :(得分:4)

这就是C ++的工作方式。编译器将尝试将您提供给它的类型隐式转换为所需的类型,即使这是一个狭窄的转换(如果执行大括号初始化也会发生异常。您会得到一个错误)。在这种情况下,它将把您给它的int转换为具有相同值的char,然后继续。

由于您提供的所有值都是[0,127]范围内的编译时间常数,因此它永远不会失败,因此您甚至都不会收到警告,可能会溢出。

如果您使用过类似的方法

Display(2000, 32, 47);

您将收到来自GCC和Clang的警告,例如

GCC
main.cpp:12:12: warning: overflow in conversion from 'int' to 'char' changes value from '2000' to ''\37777777720'' [-Woverflow]
    Display(2000, 32, 47);

Clang   
main.cpp:12:12: warning: implicit conversion from 'int' to 'char' changes value from 2000 to -48 [-Wconstant-conversion]
    Display(2000, 32, 47);

让您知道自己做的不好,但是只有知道值是什么,它才能这样做。如果有

int main()
{
    int a, b, c;
    std::cin >> a >> b >> c;
    Display(a, b, c);
    Display('a', 'b', 'c');

    return 0;
}

然后它不知道值是什么,因此不会发出警告。

如果您真的想停止此操作,则可以添加一个需要int的重载并将其删除,这样会导致类似编译器错误

void Display(char a, char b, char c)
{
   cout << a << " " << b << " " << c << endl;
}

void Display(int, int, int) = delete;

int main()
{
    int a, b, c;
    std::cin >> a >> b >> c;
    Display(a, b, c);
    return 0;
}

错误:

prog.cc: In function 'int main()':
prog.cc:31:20: error: use of deleted function 'void Display(int, int, int)'
     Display(a, b, c);
                    ^
prog.cc:25:6: note: declared here
 void Display(int, int, int) = delete;

您也可以全力以赴使用

template<typename T, typename U, typename V>
void Display(T, U, V) = delete;

,这将导致调用Display而不是3个char之外的任何错误。

答案 2 :(得分:0)

因为这些值是隐式转换的。这也称为自动类型转换。字符是整数类型,因此它们像其他任何int一样被线程化-为int分配double或float会截断该值。

这很常见,几乎所有我认为的编程语言都可以做到这一点。