В следующей строке кода:Переходя неконстантная ссылки на rvalues в C++
bootrec_reset(File(path, size, off), blksize);
Вызов функции с прототипом:
static void bootrec_reset(File &file, ssize_t blksize);
Я получаю эту ошибку:
libcpfs/mkfs.cc:99:53: error: invalid initialization of non-const reference of type 'File&' from an rvalue of type 'File'
libcpfs/mkfs.cc:30:13: error: in passing argument 1 of 'void bootrec_reset(File&, ssize_t)'
Я знаю, что вы не можете передавать неконстантные ссылки (const &
) на rvalues в соответствии со стандартом. Однако MSVC позволяет это сделать (см. this question). This question пытается объяснить, почему, но ответ не имеет смысла, поскольку он использует ссылки на литералы, которые являются угловыми и, очевидно, должны быть запрещены.
В данном примере видно, что следующий порядок событий будет происходить (как это происходит в MSVC):
File
«s конструктор будет вызван.- Ссылка на
File
иblksize
, помещается в стек. bootrec_reset
используетfile
.- После восстановления с
bootrec_reset
, временныйFile
уничтожен.
Необходимо указать, что ссылка File
должна быть неконстантной, поскольку она является временным дескриптором файла, на который вызывается неконтентные методы. Кроме того, я не хочу передавать аргументы конструктора File
на bootrec_reset
, который должен быть построен там, и я не вижу причин вручную создавать и уничтожать объект File
в вызывающем.
Так что мои вопросы:
- Что оправдывает стандарт C++, не о запрете на константные ссылки таким образом?
- Как я могу заставить GCC разрешить этот код?
- Имеет ли новый стандарт C++ 0x это в любом случае, или есть что-то, что новый стандарт дает мне, что более уместно здесь, например, все это смехотворное о ссылках на rvalue?
Я не знал, что lvalues были преобразованы во временные числа при привязке к ссылкам. Если это решение имеет смысл. * edit *: Я только что протестировал его, а они нет? –
@Matt: правила изменены с помощью C++ 0x. Это изменение правила затрагивает, например, передавая 'std :: auto_ptr' в качестве аргумента. Во всяком случае, при привязке к ссылке на const, а фактический аргумент не относится к требуемому типу (или производному классу), тогда необходимо обязательно ввести временное. Cheers, –
@Matt: Что вы точно проверили? Мой фрагмент не должен компилироваться, потому что C++ явно запрещает привязывать non-const ref к временному (последние MSVC++ и g ++ замечают это); изменение ref в const ref, конечно же, приведет к сбою компиляции из-за '++ x;'. –