Можно ли написать явный конструктор, который облегчает инициализацию копирования? - PullRequest
0 голосов
/ 08 января 2019

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

mystring.h

  class string final {
    private:
      static constexpr std::size_t default_capacity_ = 0;
      std::size_t current_capacity_;
      std::size_t sz_;
      std::unique_ptr<char[]> ptr_;
    public:
      explicit string(char);  // [1]
      string();
      string(const string&);
      string(string&&) noexcept;
      string(const char*);  // Undefined behavior if the input parameter is nullptr.
      ~string() noexcept;
  };

mystring.cpp

  string::string(char ch) {
    sz_ = 1;
    current_capacity_ = get_appropriate_capacity(sz_);
    ptr_ = std::make_unique<char[]>(current_capacity_ + 1);
    ptr_.get()[0] = ch;
    ptr_.get()[1] = '\0';
  }

  string::string(const char* c_string) {    // [2]
    sz_ = std::strlen(c_string);
    current_capacity_ = get_appropriate_capacity(sz_);
    ptr_ = std::make_unique<char[]>(current_capacity_ + 1);
    std::memcpy(ptr_.get(), c_string, sz_ + 1);
  }

test.cpp

#include "my_string.h"

using namespace kapil;

int main() {
  string z8 = 'c';  // [3]
  return 0;
}

В этом примере [3] не компилируется, так как конструктор string(char ch) для строки явный. [3] выдает следующую ошибку:

error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
   string z8 = 'c';
               ^~~
In file included from test_string.cpp:1:0:
my_string.h:22:7: note:   initializing argument 1 of ‘kapil::string::string(const char*)’
       string(const char*);  // Undefined behavior if the input parameter is nullptr.

Если сделать его неявным, код будет работать, но он также допустит операторы, подобные приведенным ниже:

string s = 144;  // [4]

У меня есть следующие вопросы в этом контексте:

[a] Есть ли способ, используя «явный» конструктор, включить string s = 's';, но не string s = 144;

[b] Ошибка, вызванная [4], показывает, что он пытается сопоставить вызов конструктора с string(const char*), почему это так? при условии, что у нас есть конструктор string(char ch).

[c] Если нет способа достичь [a] с помощью «явного» конструктора, то каков (правильный) способ его достижения.

P.S. Этот код показывает частичную реализацию. Пожалуйста, посетите https://github.com/singhkapil2905/cplusplus-string-implementation, чтобы увидеть полную реализацию.

Спасибо за любую помощь:)

1 Ответ

0 голосов
/ 08 января 2019

Компилятор пытается сопоставить конструктор string(char const *) просто потому, что другой - explicit, и поэтому игнорируется при инициализации копирования.

Чтобы разрешить инициализацию копирования из char, первым шагом действительно является реализация string(char) как не-explicit. Тогда вам нужно предотвратить инициализацию копирования из int, чтобы избежать преобразования в char. Вы можете сделать это, просто предоставив и удалив конструктор, который лучше соответствует:

string(int) = delete;

Обратите внимание, что в любом случае string s('a'); работает и с конструктором explicit, так как это прямая инициализация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...