неявное и явное преобразование из моего класса в строку - PullRequest
1 голос
/ 30 марта 2020

Мой класс подобен:

class X {

public:
        :
        :
        :
  operator const char*() const { return "foo"; };
  operator std::string() const { return std::string( "foo" ); };
        :
        :
        :
};

Я надеялся, что смогу неявно инициализировать std :: string, как это, но огромную стену ошибок:

string s1( x );

Даже явно не работает:

string s1( (string) x );

Однако приведение x к (const char*) работает нормально:

string s1( (const char*) x );

В дополнение к любому решению, которое у вас есть, ребята, любые другие рекомендации для создания тип, который должен быть как свободно конвертируемым в строки типа C, так и из std:string? (У меня уже есть конструкторы для X, принимающие const char* и std::string, а также x, и могу принимать назначения из этих типов.

1 Ответ

0 голосов
/ 30 марта 2020

Я не уверен, что мое объяснение будет на 100% точным, но если нет, надеюсь, кто-то разъяснит это. Вместо std::string и char* я буду использовать собственный класс Y и int для простоты:

struct Y 
{
   Y(int) { }
};

struct X
{
   operator int() const { return 1; }
   operator Y() const { return Y(0); }
};

int main()
{
   X x;
   Y y(x);
}

С этим кодом в C ++ 11 / 14 , у компилятора есть два варианта действий:

  1. Он преобразует x в Y(0) на X::operator Y(), а затем передает этот Y(0) в движение конструктор Y.

  2. Он преобразует x в int(1) на X::operator int() и затем передает это int(1) в конструктор преобразования Y::Y(int).

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


В C ++ 17 , ситуация отличается из-за гарантированного копирования elision . Здесь вызов конструктора перемещения в (1.) равен elided , и, следовательно, выбирается первая последовательность преобразования, поскольку она требует только 1 преобразования вместо 2.


Во всяком случае, эта версия:

Y y(static_cast<Y>(x));

также порождает неоднозначность в C ++ 11/14, что, я должен признать, я не понимаю.

...