Работает как ожидается — push_back вызывает конструктор TVAR(const char*).
Решил его "улучшить" и заменить конструкторы TVAR(const char*) и TVAR(const std::string&) на унифицированный конструктор TVAR(const std::string_view&).
#include <iostream>
#include <vector>
class TVAR
{
public:
TVAR(bool/*v*/) {std::cout << "TVAR: bool\n";}
TVAR(const std::string_view& /*v*/) {std::cout << "TVAR: std::string_view\n";}
};
int main()
{
std::vector<TVAR> vec;
vec.push_back("1234");
}
И огрёб, потому что начал вызываться конструктор TVAR(bool)
Реально стрёмно.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Реально стрёмно.
Классика, но да, с этим string_view примером новый повод наступить.
Наткнулся на похожее, когда NULL заменить на nullptr, начинает вызываться строковая версия.
(При этом, так получалось, что в месте, где NULL, нужна была именно булочная перегрузка)
Примерно так реконструировать можно для этого примера:
Здравствуйте, Alexander G, Вы писали:
КД>>Реально стрёмно.
AG>Классика, но да, с этим string_view примером новый повод наступить.
AG>Наткнулся на похожее, когда NULL заменить на nullptr, начинает вызываться строковая версия. AG>(При этом, так получалось, что в месте, где NULL, нужна была именно булочная перегрузка)
Я пришел к выводу, что конструкции вида "TVAR(const char*)" и "operator = (const char*)" не нужно удалять.
Вообще, как по мне, их лучше явно запретить (=delete).
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Alexander G, Вы писали: AG>Здравствуйте, Коваленко Дмитрий, Вы писали: КД>>Вообще, как по мне, их лучше явно запретить (=delete). AG>И писать всегда std::string_view("Literal") или std::string_view{} для пустой строки?
В моих трех тыщах файлов основного проекта, вылезло 21 место, где вызывается конструктор/оператор_присваивания для const char*.
Сижу, думаю
AG>Кстати, я бы тогда хелперы предложил, заодно минус лишний strlen:
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>UPD. А оно точно будет работать как ожидается? Что-то у меня сомнения насчет того, что в Size не будет включен терминальный нуль. Надо проверить
Непременно будет, и всегда. ну кроме "литералов" вроде char c[] = {'h','e','l','l',o'};, которые просто не использовать с такой функцией.
Итак, дубль два:
Здравствуйте, rg45, Вы писали:
КД>>И огрёб, потому что начал вызываться конструктор TVAR(bool) КД>>Реально стрёмно.
R>Так может, имеет смысл объявить этот конструктор как explicit?
Не думаю, чтобы это сильно помогло/защитило. А хуже точно сделает.
Я кстати, почти наступил на эти грабли (в реальном коде) когда юзал emplace_back. То есть, explicit был бы побоку.
В целом, это аналог VARIANT-а.
Тут куча конструкторов на разный вкус и цвет. И все могут вызываться неявно.
Явный конструктор для bool всю малину испортит
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
КД>Не думаю, чтобы это сильно помогло/защитило. А хуже точно сделает. КД>Я кстати, почти наступил на эти грабли (в реальном коде) когда юзал emplace_back. То есть, explicit был бы побоку. КД>В целом, это аналог VARIANT-а. КД>Тут куча конструкторов на разный вкус и цвет. И все могут вызываться неявно. КД>Явный конструктор для bool всю малину испортит
Да, грабли тут в том, что даже при явном вызове конструкторов вызывается не тот конструктор, который ожидается. Поэтому explicit погоды не делает.
--
Не можешь достичь желаемого — пожелай достигнутого.
AG>И писать всегда std::string_view("Literal") или std::string_view{} для пустой строки?
AG>Кстати, я бы тогда хелперы предложил, заодно минус лишний strlen:
Так clang/gcc давно считают strlen в compile time для строковых литералов,
откуда лишний strlen?
Здравствуйте, rg45, Вы писали:
КД>>Не думаю, чтобы это сильно помогло/защитило. А хуже точно сделает. КД>>Я кстати, почти наступил на эти грабли (в реальном коде) когда юзал emplace_back. То есть, explicit был бы побоку. КД>>В целом, это аналог VARIANT-а. КД>>Тут куча конструкторов на разный вкус и цвет. И все могут вызываться неявно. КД>>Явный конструктор для bool всю малину испортит
R>Да, грабли тут в том, что даже при явном вызове конструкторов вызывается не тот конструктор, который ожидается. Поэтому explicit погоды не делает.