Почему мой конструктор с неконстантной ссылкой в ​​качестве аргумента может вызываться с временными объектами? - PullRequest
7 голосов
/ 07 июня 2011

У меня есть пример кода ниже.

#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 принимает аргумент в качестве неконстантной ссылки, он прекрасно компилируется, а функция fun не компилируется. Это специфично для компилятора g ++ или стандарт c ++ должен что-то об этом сказать?

Edit:

g ++ -v дает это.

gcc версия 4.5.2 (Ubuntu / Linaro 4.5.2-8ubuntu4)

Ответы [ 2 ]

12 голосов
/ 07 июня 2011
 XYZ<temp> abc(temp());

Он компилируется, потому что это НЕ объявление переменной . Я уверен, что вы думаете, что это объявление переменной, когда дело в том, что это объявление function . Название функции: abc; функция возвращает объект типа XYZ<temp> и принимает один (неназванный) аргумент, который, в свою очередь, является функцией, возвращающей тип temp и не принимающей аргумента. Смотрите эти темы для подробного объяснения:

И fun(temp()) не компилируется, потому что temp() создает временный объект, и временный объект не может быть привязан к неконстантной ссылке.

Итак, исправление таково: определите шаблон вашей функции как:

template<typename T>
void fun(const T & arg) //note the `const`
{
}
5 голосов
/ 07 июня 2011

Нет, стандарт не позволяет передавать временные ссылки на неконстантные. (C ++ 0X ввел ссылку на rvalue, чтобы разрешить это в некоторых контролируемых случаях), см. 8.5.3 / 5 (что слишком долго для цитирования, значимая часть - , в противном случае ссылка должна быть на volatile const типа , но вы должны прочитать весь список случаев, чтобы знать, что они здесь не применяются).

А

XYZ<temp> abc(temp());

- это просто еще один пример самого неприятного анализа.

...