我什么时候会收到 "overloaded definition needed" 错误?
When do I get "overloaded definition needed" error?
举个简单的例子:
#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() 调用会出现错误,即:
No definition for Display() that takes (int, int, int) found.
No definition for Display() that takes (double, double, double) found.
然后我将不得不重载 Display() 并添加接受适当参数的那些。
那么在什么情况下我会收到语法错误?为什么在这种情况下我没有收到错误消息?
因为值是隐式转换的。这也称为自动类型转换。字符是整数类型,因此它们像任何其他 int 一样被线程化 - 将 double 或 float 分配给 int 将截断该值。
这很常见,几乎我能想到的所有编程语言都这样做。
int
可以转换为 char
因为 Standard conversions/Integral convesions.
A prvalue of an integer type can be converted to a prvalue of another integer type. A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.
整数类型的定义见Basic concepts/Fundamental types.
Types bool
, char
, char16_t
, char32_t
, wchar_t
, and the signed and unsigned integer types are collectively called integral types. A synonym for integral type is integer type.
由于 Standard conversions/Floating-integral conversions.,A double
也可以转换为 char
A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded.
这就是 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 ''777777720'' [-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
s 的重载并删除它,这样它会导致编译器错误,如
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
s 之外的任何错误。
举个简单的例子:
#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() 调用会出现错误,即:
No definition for Display() that takes (int, int, int) found.
No definition for Display() that takes (double, double, double) found.
然后我将不得不重载 Display() 并添加接受适当参数的那些。
那么在什么情况下我会收到语法错误?为什么在这种情况下我没有收到错误消息?
因为值是隐式转换的。这也称为自动类型转换。字符是整数类型,因此它们像任何其他 int 一样被线程化 - 将 double 或 float 分配给 int 将截断该值。
这很常见,几乎我能想到的所有编程语言都这样做。
int
可以转换为 char
因为 Standard conversions/Integral convesions.
A prvalue of an integer type can be converted to a prvalue of another integer type. A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.
整数类型的定义见Basic concepts/Fundamental types.
Types
bool
,char
,char16_t
,char32_t
,wchar_t
, and the signed and unsigned integer types are collectively called integral types. A synonym for integral type is integer type.
由于 Standard conversions/Floating-integral conversions.,
A double
也可以转换为 char
A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded.
这就是 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 ''777777720'' [-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
s 的重载并删除它,这样它会导致编译器错误,如
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
s 之外的任何错误。