在windows平台上使用Clang3.7
见以下代码:
class A1
{
public:
A1(char* name){}
virtual ~A1() {}
private:
A1(const A1&) {}
};
class B1 : public A1
{
public:
B1(): A1(""){}
};我得到以下错误:
MyFile(31): 8: error: base class 'A1' has private copy constructor
B1(): A1(""){}
^
MyFile(25): 2: note: declared private here
A1(const A1&) {}
^使A1复制构造函数公开,消除错误!
这里发生何事?
注意:通过改变(我应该做的)
A1(const char* name)我没有收到任何错误,并且都按预期进行编译。
发布于 2016-06-23 10:21:06
您不能使用字符串文本调用构造函数A1(char* name),因为字符串文本不能转换为char* (这种不推荐的转换在c++11之前确实存在)。或者说,调用构造函数的程序格式不正确,并且允许实现拒绝编译。
因此,重载解析会寻找其他替代方案。具有相同数量的参数的唯一其他可能的替代方法是复制构造函数。
出于任何原因,clang似乎更喜欢从string文字到A1的隐式转换,从而创建一个临时的,可以用于复制初始化,而不是直接从文字构造。这种行为会导致令人困惑的编译错误。
这两种选择都是错误的,而且clang对此发出了适当的警告:warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]。如果您将标准模式设置为比c++11更早的模式(在这种情况下,程序将是格式良好的,即使它确实使用了不推荐的转换),程序也会编译。有趣的是,如果我们不允许转换,那么即使在当前的标准模式下,程序也会编译:
class A1
{
public:
explicit A1(char* name){} // note the explicit
virtual ~A1() {}
private:
A1(const A1&) {}
};G++的行为不同,您的程序编译得很好(当然有适当的警告)。在这方面,这两个汇编者似乎都遵守了标准。
故事的寓意:永远也要读警告。在这种情况下,警告是非常清楚的,并且很容易解决,而相同的错误间接地导致了一个错误,对解决错误没有帮助。
发布于 2016-06-23 10:17:58
我想,这只是诊断是如何产生的一个假象。
char*的人不匹配privateA1参数实例化临时""以使其工作。private构造函数。有人可能会说,这是一个执行质量问题。
有趣的是,GCC 6.1.0 (even in pedantic C++14 mode) compiles your code as originally written,只对断线的文字转换发出警告。
https://stackoverflow.com/questions/37988456
复制相似问题