在Windows平台上使用Clang 3.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)
我没有错误,所有编译都按预期编译
答案 0 :(得分:6)
我想这只是生成诊断的假象。
char*
与private
不匹配A1
""
参数中实例化临时private
以使其正常工作$timeout(queryCallback, 100, false);
构造函数一个可能认为这是一个执行质量问题。
有趣的是,GCC 6.1.0 (even in pedantic C++14 mode) compiles your code as originally written只吐出了破坏的字面转换的警告。
答案 1 :(得分:3)
您不能使用字符串文字调用构造函数Categories
,因为字符串文字不能转换为A1(char* name)
(这种弃用的转换确实存在于c ++ 11之前)。或者更确切地说,一个调用构造函数的程序格式不正确,并允许实现拒绝编译。
因此,重载决策寻找其他替代方案。具有相同数量参数的唯一其他可能的替代方案是复制构造函数。
无论出于何种原因,clang似乎更喜欢从字符串文字到char*
的隐式转换,从而创建一个临时的,可用于复制初始化,而不是使用文字的直接构造。此行为导致令人困惑的编译错误。
两种选择都是格式不正确的,并且铿锵有力地警告它:A1
。如果你将标准模式设置为早于c ++ 11(在这种情况下,程序将是格式良好的,即使它确实使用了不推荐的转换),程序也会编译。有趣的是,如果我们不允许转换,那么即使在当前的标准模式下,程序也会编译:
warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
G ++表现不同,你的程序编译得很好(当然还有适当的警告)。两个编译器似乎都符合这方面的标准。
故事的道德:总是阅读警告。在这种情况下,警告非常清楚,并且易于解决,而同一个错误间接导致错误,这对于解决错误没有帮助。