2013-11-09 3 views
6
типы

Standard C++, такие как межд или полукокса имеют ctors, так что вы можете иметь такие выражения, как:Передача анонимную переменную по ссылке

int a = int(67); // create anonymous variable and assing it to variable a 
int b(13);  // initialize variable b 
int(77);   // create anonymous variable 

, определяемых пользователем типов (структур или классов) могут сделать то же самое:

struct STRUCT 
{ 
    STRUCT(int a){} 
}; 

STRUCT c = STRUCT(67); 
STRUCT d(13); 
STRUCT(77); 

Вопрос в том, почему мы можем проходить по ссылочной анонимной структуре или экземплярам класса, но не можем передавать стандартные типы?

struct STRUCT 
{ 
    STRUCT(int a){} 
}; 

void func1(int& i){} 
void func2(STRUCT& s){} 
void func3(int i){} 
void func4(STRUCT s){} 

void main() 
{ 
    //func1(int(56)); // ERROR: C2664 
    func2(STRUCT(65)); // OK: anonymous object is created then assigned to a reference 
    func3(int(46)); // OK: anonymous int is created then assigned to a parameter 
    func4(STRUCT(12)); // OK: anonymous object is created then assigned to a parameter 
} 
+4

Ваша строка 'func2' не должна компилироваться (по той же причине, что и первая). – Mat

+0

'void main()' является нестандартным. –

+0

С соответствующим уровнем предупреждения вы получите 'предупреждение C4239: используется нестандартное расширение: 'argument': преобразование из 'STRUCT' в 'STRUCT &'; Неконстантная ссылка может быть привязана только к lvalue'. Вы должны использовать '/ W4'. –

ответ

2

Если ваш компилятор разрешает это, то это не стандартный совместимый компилятор C++. Вы не можете привязать временное значение rvalue к неконстантной ссылке lvalue. Это правило. Оба clang и gcc не скомпилируют этот код для func2(STRUCT(65));.

Вместо вас есть альтернативы:

void func1(int&& i){} 

void func1(const int& i){} 

Наследство от C++ 03: A (именующая) ссылка на неконстантный тип (int &i) предполагается возможность изменить параметр затем передать временный объект, таким поскольку 56 не является логичным, потому что он не изменчив. Ссылка на тип const (const int &i) должна просто наблюдать за значением как только для чтения, тогда передача временного значения, такого как 52, является законной.

В C++ 11 вы можете ссылаться на неконстантный временный объект на &&.

5

Кажется, что вы используете компилятор MS VC++ с такой ошибкой. :) Вам нужно связать временный объект с ссылкой на const. Например, вы можете написать

const int &ri = 10; 

, но вы не можете писать

int &ri = 10; 

То же самое справедливо для определенных пользователем типов.

const STRUCT &rs = STRUCT(10); 

STRUCT &rs = STRUCT(10); // the compiler shall issue an error. 
0

В C++, анонимный временный объект всегда right-value.To принять правое значение в качестве аргумента, вы можете:

1) .void foo1 (ТИП); // прохождение по значению
2) .void foo2 (const TYPE &); // прохождение по заданию const
3) .void foo3 (TYPE & &); // в C++ 11, прохождение по правильному значению

Ваши «func3» и «func4» принимают аргумент, переданный по значению, это нормально.
Однако «func1» и «func2» могут принимать только аргумент, который передается ссылкой на значение слева. Так что неправильно передавать анонимный параметр.

Смежные вопросы