【问题标题】:Why is my constructor with non const reference as argument allowed to be called with temporary objects?为什么允许使用临时对象调用具有非 const 引用作为参数的构造函数?
【发布时间】:2011-06-07 16:06:31
【问题描述】:

我在下面有一个示例代码。

#include<iostream>

template<typename T>
class XYZ
{
   private:
   T & ref;
   public:
   XYZ(T & arg):ref(arg)
   {
   }
};
class temp
{
   int x;
   public:
   temp():x(34)
   {
   }
};
template<typename T>
void fun(T & arg)
{
}
int main()
{
   XYZ<temp> abc(temp());
   fun(temp());  //This is a compilation error in gcc while the above code is perfectly valid. 
}

在上面的代码中,即使 XYZ 构造函数将参数作为非 const 引用,它也可以正常编译,而 fun 函数无法编译。这是特定于 g++ 编译器还是 c++ 标准必须对此有所说明?

编辑:

g++ -v 给出了这个。

gcc 版本 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)

【问题讨论】:

  • 您应该指定您使用的 g++ 版本。

标签: c++ most-vexing-parse


【解决方案1】:
 XYZ<temp> abc(temp());

它可以编译,因为它不是 variable 声明。我确定您认为它是一个变量声明,而事实上它是一个 function 声明。函数名称为abc;该函数返回一个XYZ&lt;temp&gt; 类型的对象并接受一个(未命名的)参数,而该参数又是一个返回temp 类型且不接受任何参数的函数。有关详细说明,请参阅这些主题:

fun(temp()) 无法编译,因为temp() 创建了一个临时对象,而临时对象不能绑定到非常量引用。

所以解决方法是这样的:将你的函数模板定义为:

template<typename T>
void fun(const T & arg) //note the `const`
{
}

【讨论】:

  • 纳瓦兹,你很准。当我添加另一个名为 memberFun 的成员函数并尝试使用 abc 调用它时,我收到以下错误“temp.cpp:41:8: error: request for member 'memberFun' in 'abc', which is non-class type' XYZ(temp (*)())."
  • @chappar:没错。 abc 不是 XYZ&lt;temp&gt; 类型的对象。这就是为什么您不能使用abc 调用XYZ&lt;temp&gt; 的任何成员函数。
【解决方案2】:

不,标准不允许将临时引用传递给非 const 引用。 (C++0X 引入了右值引用以在某些受控情况下允许这样做),请参阅 8.5.3/5(我无法引用,有意义的部分是 否则,引用应为非volatile const 类型,但您必须阅读整个案例列表才能知道它们不适用于此处)。

还有

XYZ<temp> abc(temp());

只是另一个最令人烦恼的解析示例。

【讨论】:

  • 回答了一半。
猜你喜欢
  • 2014-11-22
  • 1970-01-01
  • 2016-12-17
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多