是否可以编写便于副本初始化的显式构造函数

Is it possible to write explicit constructor that facilitates copy initialisation?

本文关键字:初始化 副本 构造函数 于副本 是否      更新时间:2023-10-16

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

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] = '';
}
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*)匹配,为什么会这样?假设我们有一个构造函数CCD_ 5。

[c] 如果没有办法用"显式"构造函数实现[a],那么实现它的(正确)方法是什么?

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

感谢您的帮助:)

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

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

string(int) = delete;

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