2013-02-12 3 views
0

Я думаю, что это правильный код в MSVC:Инициализировать указатель на примитивный временный объект

MyClass* pMc = &MyClass(); 

Однако, когда я пытаюсь сделать то же самое с примитивными типами данных я получаю ошибка компиляции.

int* pInt = &int(); 

Ошибка:

error C2101: '&' on constant 

У меня есть 3 вопроса:

  1. Почему int() дают мне постоянный?
  2. Почему ошибка C2101 существует в первую очередь? что случилось с получением адреса константы?
  3. Есть ли способ, который я мог бы объявить int (или другие примитивные) ссылки, указывающие на временные объекты? (То есть, без создания локальной переменной первого)

О 3 вопроса:

Я не хотите сделать что-то вроде этого:

int i = int(); 
int* pInt = &i; 

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

+0

Вы понимаете, что 'int()' потенциально совпадает с '0'? Таким образом, ваше утверждение эффективно эквивалентно '& 0', что не имеет большого смысла. – 0x499602D2

+0

Также '& MyClass()' не вполне допустимый код, он не должен компилироваться.MSVC++ глупо это допускает. –

+2

Неконстантные ссылки на временные разделы запрещены стандартом, хотя MSVC имеет расширение, чтобы обойти это. Лучше не пытаться взломать решение с неопределенным поведением. – chris

ответ

4

Я не знаю ответа на 1 (я думаю, что ошибка не так, потому что я уверен, что int() не является постоянной), но

(2) Принимая адрес временного незаконна , Ваш код не должен компилироваться, но это происходит из-за нестандартного расширения MSVC++.

(3) Да, использовать RValue ссылку или константные ссылки именующих:

const int& tmp = int(); 
int&& tmp = int(); // same as former but isn't const 

Срока службы временного будет продлен до тех пор, пока ссылка выходит из области видимости.

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

int tmp; 
+0

Тот факт, что это расширение объясняет все. И, как я упоминал в комментариях, у меня нет причин, я спрашиваю об этом. Большое спасибо! – MasterMastic

1

Строка кода компилирует в один компилятор таким образом, что нарушает стандарт, но разыменования этот указатель является неопределенное поведение на следующей строке. Так что будь осторожен.

Я думаю, что это может работать:

template<typename T> 
T* make_tmp_ptr(T&&t) { 
    return &t; 
} 

Затем вызовите make_tmp_ptr(int()), и вы получите указатель на временный int, что будет продолжаться до конца выражения.

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