Значок имеет тип набора и оператор случайного элемента, унарный"?", таким образом, выражение
? set( [1, 2, 3, 4, 5] )
произведет случайное число между 1 и 5.
случайное семя инициализируется к 0, когда программа запущена, так для приведения к различным результатам на каждом использовании выполнения randomize()
В Два первых случая будут иметь место оптимизация RVO. RVO - это старая функция, и большинство компиляторов ее поддерживают. Последний случай - это так называемый NRVO (названный RVO). Это относительно новая функция C ++. Стандарт позволяет, но не позволяет Это требует реализации NRVO (а также RVO), но некоторые компиляторы поддерживают его.
Вы можете прочитать больше о RVO в пункте 20 книги Скотта Мейерса More Effective C ++. 35 новых способов улучшить ваши программы и дизайн .
Вот хорошая статья о NRVO в Visual C ++ 2005.
Все случаи верны. Все они построят временный объект и применит конструктор копирования возвращаемого типа. Обязательно, если нет конструктора копирования, код завершится ошибкой.
RVO произойдет во всех трех случаях в большинстве компиляторов. Единственное отличие - последний, где стандарт не требует этого. Это потому, что у вас есть именованная переменная. Но большинство компиляторов достаточно умны, чтобы применять к ней RVO ... чем позже объявляется именованная переменная и чем меньше преобразований она применяется, тем больше шансов, что RVO будет применен к именованной переменной.
Между прочим, возврат ссылка, конечно, возможна, как вы могли видеть в другом коде. Чего вы не должны делать, так это возвращать ссылку на локальный объект.
std::string& get_a_string2()
{
std::string str("hello");
return str; //error!
}
Как вы знаете, вызовет ошибку времени компиляции. Однако
std::string& get_a_string2(std::string& str)
{
// do something to str
return str; //OK
}
будет работать нормально. В этом случае здесь не используется конструкция или копирование. Просто функция возвращает ссылку на свой аргумент.
Это зависит от вашего компилятора - о какой платформе вы имеете в виду? Лучший способ выяснить это - скомпилировать очень небольшое тестовое приложение и проверить ASM, создаваемый вашим компилятором.
Да, это нормально, хотя вы никогда не упоминаете, что вас беспокоит; скорость? стиль? вы можете создать локальный временный объект для ссылки на константу - время жизни временного будет увеличено до времени жизни ссылки - попробуйте и убедитесь сами! (Херб Саттер объясняет это здесь ) См., Например, конец сообщения.
ИМО, вам почти всегда лучше доверять компилятору, чтобы он оптимизировал ваш код для вас. Очень мало случаев, когда вам нужно заботиться о подобных вещах (очень низкоуровневый код - одна из таких областей, где вы взаимодействуете с аппаратными регистрами).
int foo() { return 42; }
int main(int, char**)
{
const int &iRef = foo();
// iRef is valid at this point too!
}
Во-первых, вполне нормально вернуть временное значение по значению, что вы и делаете. Он копируется, и хотя оригинал выходит за пределы области видимости, копия этого не делает и может безопасно использоваться вызывающим.
Во-вторых, все три случая фактически идентичны (поскольку вы не получаете доступ к временному в в любом случае третий случай), и компилятор может даже выдать один и тот же код для всех из них. Следовательно, он может использовать RVO во всех трех случаях. Это полностью зависит от компилятора.