【问题标题】:Is it possible to write explicit constructor that facilitates copy initialisation?是否可以编写有助于复制初始化的显式构造函数?
【发布时间】:2019-01-08 16:53:20
【问题描述】:

我实际上正在编写字符串的实现,并且在尝试从单个字符构造字符串时面临一个令人困惑的情况。

我的字符串.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;
  };

我的字符串.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 的构造函数 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],那么实现它的(正确)方法是什么。

附:此代码显示部分实现。 请访问https://github.com/singhkapil2905/cplusplus-string-implementation 以查看完整的实现。

感谢您的帮助:)

【问题讨论】:

    标签: c++ string c++11 compiler-errors


    【解决方案1】:

    编译器尝试匹配 string(char const *) 构造函数,只是因为另一个是 explicit,因此在复制初始化中被忽略。

    要允许从char 进行复制初始化,第一步确实是将string(char) 实现为非explicit。然后,您需要防止从int 进行复制初始化是避免转换为char。您可以通过提供和删除更匹配的构造函数来做到这一点:

    string(int) = delete;
    

    请注意,在任何情况下,string s('a'); 也可以与 explicit 构造函数一起使用,因为它是直接初始化的。

    【讨论】:

    • 谢谢昆汀 :)
    猜你喜欢
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2014-05-20
    • 2021-02-20
    相关资源
    最近更新 更多