Подтвердить что ты не робот

Почему мой перегруженный конструктор С++ не вызван?

У меня есть класс вроде этого:

class Test{
public:
  Test(string value);
  Test(bool value);

};

Если я создам такой объект:

Test test("Just a test...");

Вызывается конструктор bool!

Кто-нибудь знает, почему?

Спасибо

4b9b3361

Ответ 1

Тип "Just a test..." - const char *, который может быть неявно преобразован либо в bool, либо std::string. Поскольку std::string не является встроенным типом, const char * преобразуется в bool. Вы можете предотвратить это путем явного преобразования const char * в std::string:

Test test(std::string("Just a test..."));

Ответ 2

Это хорошо известное раздражение С++.

В строковом литерале есть тип chat const []. У вас есть два конструктора, последовательности конверсий из char const [] в Test выглядят следующим образом:

1) char const [] → char const * → bool

2) char const [] → char const * → std::string

1) является встроенным стандартным преобразованием, тогда как 2) является пользовательским преобразованием. Встроенные преобразования имеют приоритет над пользовательскими преобразованиями, поэтому ваш строковый литерал легче конвертируется в bool, чем в std::string.

Ответ 3

Тип "Just a test..." - const char*. Существует встроенное преобразование из указателей в bool, которое предпочтительнее, чем встроенное преобразование от const char* до std::string.

Причина, по которой преобразование bool является предпочтительным, состоит в том, что std::string, будучи частью стандартной библиотеки, не является встроенным типом типа, целым числом, указателями и логическими. Он действует как любой другой класс, поэтому его конструкторы преобразования учитываются только после преобразования в встроенные типы.

Ответ 4

Один из способов обойти эту проблему состоит в том, чтобы предоставить другой конструктор, содержащий const char *, а затем явно преобразовать в std::string.

Ответ 5

Когда у вас есть конструктор (особенно несколько конструкторов), который принимает только один аргумент, может оказаться целесообразным объявить их "явными", чтобы избежать подобных сюрпризов. Это заставляет пользователя класса удостовериться, что он дает правильный тип конструктору, который он хочет использовать, и предотвращает выполнение этих неявных преобразований типа за спиной пользователей и затрудняет поиск ошибок.

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=15&rll=1

В С++ 0x это было расширено для операторов преобразования, чтобы предотвратить такую ​​же проблему.

http://www2.research.att.com/~bs/C++0xFAQ.html#explicit-convertion

Ответ 6

Один из способов - создать переменную типа std::string и передать переменную в:

std::string test = "TEST";
A a(test);

Таким образом, тип явно определен как std::string, он не будет по умолчанию для конструктора, который принимает bool