C++ 构造函数阻止成功编译

标签 c++ copy-constructor initializer-list

我在 C++ 中遇到了一个奇怪的问题,希望得到解释。此代码段无法编译:

size_t bufLength = 18;
char* buffer = new char[bufLength];
auto_array_ptr<char> pBuffer1 = buffer;  // fails
auto_array_ptr<char> pBuffer2(buffer);

上面的第 3 行失败并返回 No viable constructor copying variable of type 'auto_array_ptr<char>' .请注意,下一行编译得很好。

Q1) 这本身对我来说很奇怪。我认为在必要时使用赋值进行初始化已转换为使用初始化器进行初始化。如果第二个成功,为什么第一个会失败?

Q2) 但真正让我困惑的是,当我从 auto_array_ptr删除 一个构造函数时,失败的行成功了类别:auto_array_ptr(auto_array_ptr)构造函数。我真的很难理解这里发生了什么。

我可以想象一下编译器可能会在这里尝试做什么的场景:

1- 寻找空白 operator=(char *p) .未找到。让我们看看是否可以推广论点 (buffer)。 2-啊啊,有个operator=(auto_array_ptr&) .所以如果我能推广我就赢了bufferauto_array_ptr .让我们寻找一个构造函数来做到这一点。 3-啊啊有个auto_array_ptr(auto_array_ptr&)构造函数。因此,让我们从 buffer 构建一个临时变量使用该构造函数( temp )。 4- 现在尝试使用 operator=(auto_array_ptr&) , 方法。但是真可惜:它的论点不是const ,我实际上无法使用它。报告错误。

但是这个场景并没有说服力。其一,编译器可能会注意到 const问题是第 2 步。此外,它可以使用 auto_array_ptr(char *)直接而不是试图推广buffer .然后,如果我添加 operator=(char *p)上课,错误不会消失。最后,这并不能解释为什么删除 auto_array_ptr(auto_array_ptr&)有帮助。

当然你需要auto_array_ptr的来源.这是:

template<class T>
class auto_array_ptr
{
public:
    auto_array_ptr(T *p = 0) : ptr(p) {}
    auto_array_ptr(auto_array_ptr<T>& a) : ptr(a.release()) {}  // remove this line to compile
    ~auto_array_ptr() {if(ptr != 0) {delete[] ptr; ptr = 0;}}

    void operator=(auto_array_ptr<T>& a) {if(&a != this) reset(a.release());}
//    void operator=(T *p) { if(p != ptr) reset(p);}    // adding this doesn't help

    T& operator[](int i) const {return ptr[i];}
    T& operator[](unsigned int i) const {return ptr[i];}
    operator T*() const {return ptr;}
    T* get() const {return ptr;}

    T* release() {T* tmp = ptr; ptr = 0; return tmp;}

    void reset(T *p = 0) {if(ptr != 0) {delete[] ptr;}; ptr = p;}

private:
    T *ptr;
};

编译器是在 Mac OS X Lion 下的 Xcode 4.4 中运行的最新版本的 Clang。我相信它基于 LLVM 3.1。 Xcode 4.5 中稍微更新的版本的行为完全相同。

谢谢。

最佳答案

auto_array_ptr<char> pBuffer1 = buffer;  // fails

创建 temporary auto_array_ptr<char>来自 buffer并将其复制到 pBuffer1 .

auto_array_ptr(auto_array_ptr<T>& a)

你的copy c-tor接收reference .您不能绑定(bind) temporaryreference ,所以,编译失败。

Q2) But the real puzzle for me is that the failing line succeeds when I remove a constructor from the auto_array_ptr class: the auto_array_ptr(auto_array_ptr) constructor. I really have a hard time understanding what's happening here.

编译器将创建 copy c-torsignature

auto_array_ptr(const auto_array_ptr&)

关于C++ 构造函数阻止成功编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12248283/

相关文章:

c++ - qml : data models in models 中的嵌套列表

c++ - std::function 到可变参数成员函数,然后绑定(bind)可变参数模板参数

C++/C 虚拟/可嵌入文件系统 [交叉兼容(库)]?

c++ - 使用重载赋值运算符

Java克隆浅拷贝深拷贝复制构造函数嵌套对象

c++ - 如何使用 initializer_ist 在构造函数中初始化动态数组?

c++ - initializer_list 和 move 语义

c++ - int 到 float 转换的精度损失

c++ - 在继承的对象中切片

具有复杂结构的 C++ 初始化列表