5

在 Linux 上使用 C++,我只是相当愚蠢地写了这个:

struct in_addr ip_addr = ((struct sockaddr_in)socket_addr).sin_addr;

而不是预期的:

struct in_addr ip_addr = ((struct sockaddr_in*)&socket_addr)->sin_addr;

给我这个错误:

"error: no matching function for call to ‘sockaddr_in::sockaddr_in(sockaddr&)"

我知道为什么会出现错误(我试图转换结构),但我不明白为什么错误消息说明了它的作用。有人可以解释一下吗?

4

3 回答 3

5

当编译器遇到 C 风格的强制转换时,它会尝试将其解释为一个或两个 C++ 风格的强制转换,顺序如下:

  • const_cast<new_type>(expression)
  • static_cast<new_type>(expression)
  • static_cast (with extensions)其次是const_cast
  • reinterpret_cast<new_type>(expression)
  • reinterpret_cast其次是const_cast

选择满足相应强制转换运算符要求的第一个选项,即使它无法编译。

在你的情况下,static_cast<sockaddr_in>(socket_addr)被选中。这是直接初始化,因此编译器会寻找但没有找到一个构造函数,该构造函数接受const对被强制转换的对象的引用。

请注意,相同的转换在应用于指针时不会触发错误,因为语言在不同类型的指针之间具有内置转换。

于 2017-05-17T10:03:14.950 回答
4

在对类型(而不是指针)进行强制转换时,编译器会尝试调用其构造函数,该构造函数采用sockaddr_insocket_addr. 由于该构造函数不存在,编译器会抛出您显示的错误。

于 2017-05-17T09:57:04.517 回答
2

因为这就是强制转换的工作方式——它们将 a 转换A为 a B,并且(除非B是指针或引用)需要调用转换运算符或构造函数。编译器试图找到一个构造函数来sockaddr_in从 a创建一个sockaddr; 不存在,因此错误。

它无法猜测您真的打算尝试转换为其他东西。

我发现成为一名高效的 C++ 程序员的很大一部分是学习处理这些编译器错误并使用它们来启发式地确定实际问题可能是什么的艺术。;)

于 2017-05-17T10:07:38.160 回答