2011-06-07 68 views
7

我有一个示例代码如下。为什么我的构造函数允许使用临时对象调用非const引用作为参数?

#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引用上面的代码,它虽然有趣功能无法编译编译罚款。这是特定于g ++编译器还是C++标准需要说些什么?

编辑:

g ++ -v给出了这个。

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

+0

++您正在使用您应指定克的版本。 – Gabe 2011-06-07 16:11:00

回答

12
XYZ<temp> abc(temp()); 

它编译,因为它不是一个变量声明。我相信你认为它是一个变量声明,当事实是它的一个函数声明。该函数的名称是abc;该函数返回一个类型为XYZ<temp>的对象,并接受一个单一的(未命名的)参数,该参数又是一个返回类型temp并且不带参数的函数。请参阅以下主题,详细解释:

而且fun(temp())不能编译,因为temp()创建一个临时的对象和临时对象不能被绑定到非const引用。

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

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

纳瓦兹,你是现货。当我添加另一个名为memberFun的成员函数并尝试使用abc调用该函数时,出现以下错误“temp.cpp:41:8:error:'abc'中的成员'memberFun'的请求,它是非类类型' XYZ (temp(*)())“。 – chappar 2011-06-07 16:25:03

+0

@chappar:的确如此。 'abc'不是'XYZ '类型的对象。这就是为什么你不能使用'abc'调用'XYZ '的任何成员函数。 – Nawaz 2011-06-07 16:27:01

5

否,标准不允许通过临时非const引用。 (C++ 0X在某些受控的情况下引入了右值引用以允许这样做),参见8.5.3/5(这对于我来说太长了,有意义的部分是,否则引用应该是非易失性常量键入,但您必须阅读整个案例列表以了解它们不适用于此)。

而且

XYZ<temp> abc(temp()); 

是最让人头疼的解析的只是又一个例子。

+2

这回答了一半的问题。 – Beta 2011-06-07 16:11:21

相关问题