我在 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- 寻找一个 void operator=(char *p)
。未找到。让我们看看我们是否可以提升论点 ( buffer
)。2-啊啊,有一个operator=(auto_array_ptr&)
。因此,如果我能晋升buffer
为auto_array_ptr
. 让我们寻找一个构造函数来做到这一点。3-啊啊有一个auto_array_ptr(auto_array_ptr&)
构造函数。buffer
因此,让我们使用该构造函数 ( )构造一个临时变量temp
。4-现在尝试使用operator=(auto_array_ptr&)
, 方法。但是很糟糕:它的论点不是const
,我实际上不能使用它。报告错误。
但这种情况并不令人信服。一方面,编译器可能会注意到const
问题出在第 2 步。此外,它可以auto_array_ptr(char *)
直接使用而不是尝试提升 buffer
. 然后,如果我将 a 添加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 中稍微更新的版本的行为完全相同。
谢谢。