Например, "не пользуйся new/delete, пользуйся умными указателями".
Или "не пользуйся конструкторами с круглыми скобками, пользуйся {}. И порядок зафиксирует и от кучи проблем избавит.".
Увы, новые конструкции просто создают другое подмножество проблем.
Вот к примеру, что выведет вот такой код?
#include <iostream>
int main() {
auto a = std::string{48};
std::cout << a << std::endl;
}
Правильно, он выведет
0. Потому что идет неявное преобразование инта к чару. И chr(48) == '0'.Что характерно, вот такая строчка
auto b = std::string(48); // error: no matching function for call to
Не скомпилируется. Потому что у строки нет конструктора от char. Точнее есть, но там надо развлекаться веселее.
#include <iostream>
int main() {
auto b = std::string(48, 48.0);
std::cout << b << std::endl;
}
Это будет
000000000000000000000000000000000000000000000000
Так или иначе, но у нас новые конструкции просто создают новые проблемы.
Ну и самая большая проблема, когда эти вещи вызываются неявно.
Человек, который прислал мне похожий пример, утверждает, что он пришел из продакшн кода.
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, std::string> m;
double i = 65.5;
m["hello"] = i;
std::cout << m.at("hello");
return 0;
}
Что тут происходит? double кастится к int, int кастится к char, char кастится к string, в мапу записывается буква
A. Прекрасно!