- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
#include <iostream>
#include <functional>
using namespace std;
struct T
{
int a;
T(const T&):a(1){cout<<"copy_construct T"<<endl;}
T():a(1){cout<<"construct T"<<endl;}
~T(){a=0;cout<<"destruct T"<<endl;}
const T& operator=(const T&){cout<<"copy_ass T"<<endl;return *this;}
};
struct M: public T{};
void f(const T& fa)
{
cout<<"fa.a= "<<fa.a<<endl;
}
int main() {
f(std::cref(T()));
cout<<endl;
const T& b = T();
cout<<"b.a= "<<b.a<<endl;
cout<<endl;
const T& a = std::cref(T());
cout<<"a.a= "<<a.a<<endl;
return 0;
}
reference_wrapper нельзя использовать для temporary objects
именно потому, что они умрут при выходе из конструктора (что аналогично случаю с f)
ну а b дожил до конца, как и следовало
при выходе из функции
глаза изначально увидели f(T()), что, понятное дело, валидно
думаю, что f(std::cref(T())) - примерно тот же случай, что и const T& a = std::cref(T());
т.е. должно быть плохо
з.ы. ну и gcc-4.7 со мной согласен
: error: use of deleted function ‘void std::cref(const _Tp&&) [with _Tp = T]’
: error: use of deleted function ‘void std::cref(const _Tp&&) [with _Tp = T]’
Это радует. Очень хорошо. Но в стандарте я такой перегрузки не видел (им бы поправить его).
Даже здесь её нет:
http://en.cppreference.com/w/cpp/utility/functional/ref
Кстати, вот себя delete наконец положительно проявил.
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/reference_wrapper
>error: use of deleted function ‘void std::cref
стандарт:
>reference_wrapper( T&& x ) = delete;
Что-то они странно подошли к пониманию стандарта.
стандарт говорит, что удаляет конструктор перемещения, когда гцц говорит, что удалена функция цреф от рвалуессылки.
http://ideone.com/J1LvwT
f(a*5+r); Получается по стандарту до конца функции f должен выжить только объект t в следующем псевдокоде после раскрытия? а остальные ссылки сохраненные внутри объектов окажутся дохлыми?
это всё есть в [class.temporary]
В (std::cref(T())) - cref такая же функция, как operator* в (T()*5)
Это значит, что в обоих случаях T() должно умереть (а во втором случае ещё и объект сконструированный из 5ки, если он был) во время передачи результата следующему надвыражению, например в функцию f.
зы:
Я всегда буду обновлять тред перед постингом.
Я всегда буду обновлять тред перед постингом.
Я всегда буду обновлять тред перед постингом.
Я всегда буду обновлять тред перед постингом.
Ответили выше
глянул мельком код в ОП
глянул выхлоп
суть, что там cref в параметрах f, не увидел, поэтому ничего не заподозрил - ну и дальше рассуждал, что там просто f(T())
> Я всегда буду обновлять тред перед постингом.
только это не удобно нихера
Мне казалось, что раньше я в ней был уверен, но теперь совершенно не уверен:
Имею ли я в данном случае передать а по ссылке или по выходу из функции а может по стандарту издохнуть и ссылка будет указывать на мусор?
http://ideone.com/3hOQ63
Но что на эту тему говорит стандарт?
Вобщем ответ на мой вопрос:
Печально известный способ оптимизации функций пробрасывания ссылки сквозь ссылку: - может приводить к UB. Заглядывание в стандарт не понадобилось.
Стырил бормандовскую фишку, гад.
Я всегда буду обновлять тред перед постингом.(с)
Лишь бы ее не уродовали псевдознаком копирайта, составленным из скобок и буквы с.
http://liveworkspace.org/
(онлайн компилятор крестов самый свежий и буст)
Может куда переехал?
но он вообще давно просрал все обещанные сроки
http://www.gamedev.ru/flame/forum/?id=169251
>ideone? Или обязательно нужен буст?
Ты не поверишь:
http://ideone.com/JsvfGK
http://codepad.org/ <- слишком простой
https://compilr.com/ <- нормальный
http://krillapps.com/coderunner/ <- хороший
(покидать рабочее пространство)
Если честно, не нужен. Лайвворкспейс 1.0 был прост как пробка и всегда самый новый. За это он мне и нравился.
Если они введут мудню с регистрацией, управлением файловой системой и проектами, то это будет не приятно. Придется с него уйти.
верно
ни строчки врагу!
у меня даже логина туда нет
А на некоторых сайтах типа ВК просмотр подвала стал задачей нетривиальной...
В кресты перенесут Loki::TypeList
http://gcc.gnu.org/onlinedocs/gcc-4.7.2/libstdc++/api/a00905.html
А ещё начинают готовить рефлекшен:
Получение списка всех базовых классов класса во время кококомпиляции (интересно, как это реализовано, наверное вшили в компиль):
http://gcc.gnu.org/onlinedocs/gcc-4.7.2/libstdc++/api/a00907.html
зы:Так и есть, вшили, скукота:
http://gcc.gnu.org/onlinedocs/gcc-4.7.2/libstdc++/api/a01526_source.html
T& f(const T& fa)
{
static int i=0;
cout<<"fa.a= "<<fa.a<<" i="<<i<<endl;
while(i++<=10){
f((T&)fa);
}
return (T&)fa;
}
ты что-то этим кодом хотел про демон монстрировать?
ideone_eJDor1.cpp:9:14: error: expected �,’ or �...’ before �&&’ token
ideone_eJDor1.cpp:9:18: error: invalid constructor; you probably meant �T (const T&)’
ideone_eJDor1.cpp:14:31: error: expected �,’ or �...’ before �&&’ token
P.S. Если нормально скопировать сообщения не получается, сделай export LC_MESSAGES=C перед стартом gcc, чтобы он писал по-английски. Решается эта проблема добавлением опции -std=c++0x, т.к. код юзает фишки нового крестостандарта.
P.S. Что-за мусор в непонятной кодировке у AliceGoth я не понял...
Кстати, как у других компиляторов с указанием параметров сборки в исходнике?
у гцц такого нет, что печально
у clang, судя по всему, есть
Да было бы о чем печалиться... имхо это очень сомнительная фича.
Опции будут рассеяны по нескольким местам - часть в сборочной системе, часть в исходнике. До кучи кто-нибудь додумается добавить эту прагму в хидер (удобно же чтобы либа цеплялась сразу, когда заинклудили относящийся к ней хидер).
В результате вместо одного взгляда на командную строку компилятора/компоновщика придется потратить кучу усилий на копание в коде и всех его инклудах...
Компиляция...
outer.cpp
Linking to lib file: boost_thread-vc90-mt-1_49.lib
Linking to lib file: boost_date_time-vc90-mt-1_49.lib
Linking to lib file: boost_system-vc90-mt-1_49.lib
Linking to lib file: boost_regex-vc90-mt-1_49.lib
Linking to lib file: boost_filesystem-vc90-mt-1_49.lib
Linking to lib file: boost_chrono-vc90-mt-1_49.lib
Linking to lib file: boost_program_options-vc90-mt-1_49.lib
Linking to lib file: boost_iostreams-vc90-mt-1_49.lib
Linking to lib file: boost_zlib-vc90-mt-1_49.lib
...
тяжело для каждого проекта индивидуально настраивать весь этот список
и ведь дело не в том, что именно тебе ненужно, дело в том что другим нужно, а гцц не умеет
с другой стороны, между компилятором и линкером должна быть налажена связь - каким образом передать собранный компилятором список библиотек для линковки, и, скорее всего, это и есть настоящая причина, почему гцц не умеет
Да, походу причина именно в этом. Компилятор и линкер того же watcom'а и msvc рассчитаны на работу с тулзами из своего комплекта, и скорее всего не смогут съесть список либ, записанный в объектник, подготовленный чужим компилером.
В gcc же, видимо, не захотели привязываться к своему линкеру (хотя для link-time оптимизации, емнип, это все равно приходится делать), а чтобы при переключении на другой линкер (тот же ld) не возникало неведомых багов, пришлось отказаться от передачи инфы для него через объектники.
P.S. Кстати еще одна причина, наверное, заключается в привередливости гнутого линкера к порядку, в котором перечисляются библиотеки.
Не нужно.
В любом более-менее сложном проекте есть зависимости от каких-нибудь внешних либ. И если имя либы можно вписать в прагму, то полный путь к ней - ни в коем случае.
Вторая проблема - далеко не все опции компилятора относятся к самому исходнику. Большая часть относится к текущей сборочной конфигурации, которых как правило несколько (например debug и release).
Поэтому, имхо, такая инструкция была бы полезной разве что для лаб и прочей игрушечной фигни из одного файла.
а для debug/release обычно хватает настройки выходной директории солюшена
Почему в бусте такая схема выгоднее? А потому, что путь к его либам и хидерам прописывается один раз, а независимых либ в нем относительно много, и из них нужно подключить пяток-десяток.
Если же прицеплять типичную мелкую либу, собранную в отдельном каталоге - там профита от авто-линковки практически не будет.
Крестокомпилятор ваткома можно ещё одним добрым словом вспомнить: он поддерживает std::map на SkipList. А такой мог работать даже в многопоточной среде без локов. Насчет сравнения его производительности с RB-tree не знаю, но теже O(log n) по алгоритмической сложности.
http://ideone.com/2xrCnR
http://ideone.com/1B0Acb
Но почему виртуальность деструктора ни на что не повлияла? Неужели соптимизировал?
Также моя зайка Алёночка
http://alenacpp.blogspot.ru/2008/01/const.html
говорит, что
В данном конкретном куске кода ничего плохого я конечно не вижу.
нет, оптимизация тут не причем
надо смотреть реализацию shared_ptr в гцц, потому что с голым указателем и delete работает как положено - виртуальность имеет значение
вот тут http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr написано, что конструктор (2) использует delete expression as deleter, что может означать
а) будет честный delete inner_ptr_; как Base (чего мы не видим), и
б) deleter сформируется уже на этапе конструктора, и т.к. известен Y, то и delete сформируется как родной по Y * (и походу, так и есть)
ничего странного
был создан временный объект T
должен быть удален временный объект T
а то, что его задерживает ссылка родительского типа, компилятору не важно - имеет право, пусть задерживает
http://ideone.com/mMioMv