Используя C ++ в Linux, я просто тупо написал это:
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&)"
Я знаю, почему у меня ошибка (я пытался привести структуру), но я не понимаю, почему в сообщении об ошибке указано, что оно делает. Может кто-нибудь объяснить, пожалуйста?
Когда компилятор встречает приведение в стиле 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
ссылка на объект
Обратите внимание, что одно и то же преобразование не вызывает ошибку при применении к указателям, поскольку в языке есть встроенные преобразования между указателями разных типов.
Выполняя приведение типа (а не указателя), компилятор пытается вызвать конструктор sockaddr_in
которые принимают объект того же типа, что и socket_addr
, Так как этот конструктор не существует, компилятор выдает ошибку, которую вы показали.
Потому что так работают касты — они конвертируют A
к B
и (если B
является указателем или ссылкой), которая требует вызова оператора преобразования или конструктора. Компилятор пытается найти конструктор для создания sockaddr_in
из sockaddr
; ничего не существует, следовательно, ошибка.
Невозможно догадаться, что вы действительно хотели попробовать вместо этого перейти к чему-то другому.
Я обнаружил, что большая часть становления продуктивным программистом C ++ изучает искусство принятия этих ошибок компилятора и использования их для эвристического определения того, что фактический проблема скорее всего есть. 😉