为什么我的带有非const引用的构造函数允许使用临时对象调用?

cha*_*par 7 c++ most-vexing-parse

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

#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. 
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,即使XYZ构造函数将参数作为非const引用,它也会很好地编译,而fun函数无法编译.这是特定于g ++编译器还是c ++标准必须要说些什么呢?

编辑:

g ++ -v给出了这个.

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

Naw*_*waz 12

 XYZ<temp> abc(temp());
Run Code Online (Sandbox Code Playgroud)

它编译,因为它不是一个变量声明.我确定你认为它是一个变量声明,而事实是它是一个函数声明.函数的名称是abc; 该函数返回一个类型的对象,XYZ<temp>并获取一个(未命名的)参数,该参数又是一个返回类型temp且不带参数的函数.有关详细说明,请参阅以下主题

并且 fun(temp())不编译,因为temp()创建临时对象而临时对象不能绑定到非const引用.

所以修复是这样的:将你的功能模板定义为:

template<typename T>
void fun(const T & arg) //note the `const`
{
}
Run Code Online (Sandbox Code Playgroud)


APr*_*mer 5

不,标准不允许将临时传递给非const引用.(C++ 0X在某些受控情况下引入了rvalue引用以允许这种情况),参见8.5.3/5(对我来说太长了,引用有意义的部分,引用应该是非易失性const类型),但你必须阅读整个案例列表,知道它们不适用于此处).

XYZ<temp> abc(temp());
Run Code Online (Sandbox Code Playgroud)

只是另一个最令人烦恼的解析的例子.

  • 这回答了一半的问题. (2认同)