Ссылка, связанная с проблемой компиляции с Visual Studio 2008, но не с g ++ - PullRequest
1 голос
/ 20 марта 2012

следующий код компилируется с Visual Studio 2008 , но не с g ++ на Mac OSX:

class A
{
public:
  A CreateA()
  {
    A a;
    return a;
  }
  };

class B
{
public:
  void ComputeWithA
    (
    A &a // Here, removing the reference solves the problem
    )
  {
    return;
  }
};

int main ()
{
  A a;
  B b;

  b.ComputeWithA(a); // Works
  b.ComputeWithA(a.CreateA()); // Invalid arguments 'Candidates are: void ComputeWithA(A &)'

  return 0;
}

Почему эта ссылка связана с проблемой? Любое объяснение будет с благодарностью.

С уважением.

Ответы [ 3 ]

3 голосов
/ 20 марта 2012

Код не является законным, но VC принимает его. Ваша функция возвращает временный объект, который не может быть привязан к неконстантной ссылке (которую ваша функция принимает в качестве аргумента).

Можете ли вы изменить свою функцию, чтобы она брала свой параметр по константной ссылке?

3 голосов
/ 20 марта 2012

a.CreateA() дает вам R-значение (то есть временное значение). ComputeWithA хочет ссылку, также известную как L-Value. Стандарт гласит, что вы не можете преобразовать R- в L-значения, поэтому MSVC здесь не так.

Однако вы можете использовать константную ссылку, поскольку этот случай явно разрешен:

void ComputeWithA(A const &a) // add a const and everything works fine
0 голосов
/ 21 марта 2012

Если вы не можете изменить сигнатуру метода, есть обходной путь

class A
{
public:
A& operator()()
{
return *this;
}  
...
b.ComputeWithA(a.CreateA()()); 

Я использовал это один раз при реализации регистратора, потому что временный объект использовался в большем количестве операций.

...