为什么IBM XL C/C++编译器出现此警告?

Fre*_*son 8 c++ aix compiler-warnings

这是一个说明问题的最小代码示例:

#include <iostream>

class Thing
{
   // Non-copyable
   Thing(const Thing&);
   Thing& operator=(const Thing&);

   int n_;

public:
   Thing(int n) : n_(n) {}

   int getValue() const { return n_;}
};

void show(const Thing& t)
{
   std::cout << t.getValue() << std::endl;
}

int main()
{
   show(3);
}
Run Code Online (Sandbox Code Playgroud)

这会产生相同的错误:

int main()
{
    show( Thing(3) );
}
Run Code Online (Sandbox Code Playgroud)

AIX下的IBM XL C/C++ 8.0编译器会发出以下警告:

"testWarning.cpp", line 24.9: 1540-0306 (W) The "private" copy constructor "Thing(const Thing &)" cannot be accessed.
"testWarning.cpp", line 24.9: 1540-0308 (I) The semantics specify that a temporary object must be constructed.
"testWarning.cpp", line 24.9: 1540-0309 (I) The temporary is not constructed, but the copy constructor must be accessible.
Run Code Online (Sandbox Code Playgroud)

我还尝试使用"-Wall"和"-pedantic"g ++ 4.1.2并且没有诊断.为什么需要访问复制构造函数?我怎样才能消除警告,除了使对象可复制(在我无法控制之外)或使显式副本通过(当现实对象复制昂贵时)?

Jer*_*fin 9

其规则见标准的§8.5.3/ 5.确定了三种基本情况.第一个涉及初始化程序(在您的情况下为'3')是左值或具有类类型.由于这些都不是真的,你所拥有的是第三种情况:使用没有类类型的rvalue初始化const引用.8.5.3/5中的最后一个子弹涵盖了此案例:

否则,使用非参考拷贝初始化的规则(8.5)从初始化表达式创建并初始化类型为"cv1 T1"的临时类型.然后将引用绑定到临时.如果T1与T2有参考关系,则cv1必须与cv-qualified相同,或者cv-qualification与cv2相同; 否则,该计划是不正确的.

编辑:重读,我认为IBM做对了.我以前想过必须复制临时的可能性,但这不是问题的根源.要使用§8.5中指定的非引用副本初始化创建临时,它需要copy ctor.特别是,在这一点上,它相当于一个表达式:

T x = a;

这基本上相当于:

T x = T(a);

也就是说,需要创建一个临时的,然后将临时文件复制到正在初始化的对象(在这种情况下,这也是一个临时对象).总结所需的过程,它大致相当于代码:

T temp1(3);
T temp2(temp1); // requires copy ctor
show(temp2);    // show's reference parameter binds directly to temp2
Run Code Online (Sandbox Code Playgroud)