Есть следующий упрощённый класс:
struct ID {
int id;
std::string string_id;
template<typename String>
explicit ID(String&& string_id) : string_id{std::forward<String>(string_id)}, id{std::stoi(string_id)} {}
ID(const ID& other) : string_id{other.string_id}, id{std::stoi(other.string_id)} {}
};
Вроде как всё нормально, но когда пытаюсь вызвать конструктор копирования, получаю непонятные ошибки из explicit
конструктора... В чём проблема?
ID id1("3x5");
ID id2(id1); // ошибка
Тут целая россыпь ошибок:
string_id
имеет то же имя, что и поле класса, это чревато адской путанницейstd::forward(string_id)
пропущен параметр шаблона String
ID id2(id1);
будет более предпочтителен конструктор с универсальной ссылкой, а не копирующий (так как он принимает ID &
), для исправления достаточно сделать кастование ID id2(::std::as_const(id1));
или доработать конструктор с универсальной ссылкой использую что-нибудь вроде safe_overload
Во-первых, std::forward
требует явного указания шаблонного аргумента
string_id{std::forward<String>(string_id)}
Каким образом у вас получилось "все нормально" без вызова конструктора копирования - не ясно.
Во-вторых, ваша универсальная ссылка - "идеальный параметр", который в процессе overload resolution побеждает даже вариант с const ID&
из-за необходимости квалификационного преобразования (добавления const
) в последнем. Если вы в своем конструкторе копирования уберете const
ID(ID& other)
то "победит" именно он. А так - побеждает ваш
template<typename String> explicit ID(String&& string_id)
который в таком случае получается некорректным.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Стоит задача написать простой плагин для этой САПР системы используя инструменты NRX и фреймворк QTВ процессе работы возникла проблема, которую...
Скажите, существуют ли серьезные проекты, где в "чистом" виде используется Windows RPC для реализации клиент-серверного взаимодействия? Поиск...
Скажите, пожалуйста, как из gui приложения на C++ вызвать LPSolver? Можно пример кода?
Компилятор не ловит ошибку, потому что такой цели перед ним не ставитсяДля тех, кто может не сразу видит проблему в коде, поясню