Правила сбрасывания ссылок (за исключением A& & -> A&
, который является C ++ 98/03) существуют по одной причине: позволить идеальной переадресации работать.
«Совершенная» пересылка означает эффективную пересылку параметры, как если бы пользователь вызывал функцию напрямую (минус elision, которая нарушена пересылкой). Существуют три типа значений, которые пользователь мог бы передать: lvalues, xvalues и prvalues, и есть три способа, которыми принимающее местоположение может принимать значение: по значению, (возможно, const) lvalue reference и (возможно, const) rvalue ссылка
Рассмотрим эту функцию:
template<class T>
void Fwd(T &&v) { Call(std::forward<T>(v)); }
Если Call
принимает свой параметр по значению, то копирование / перемещение должно происходить в этот параметр. Какой из них зависит от того, что такое входящее значение. Если входящее значение является значением l, то оно должно скопировать значение lvalue. Если входящее значение представляет собой rvalue (в совокупности это значения x и prvalues), то он должен перейти от него.
Если вы вызываете Fwd
с lvalue, правила вывода типа C ++ означают, что T
будет выведено как Type&
, где Type
является типом lvalue. Очевидно, что если lvalue const
, оно будет выведено как const Type&
. Правила сбрасывания ссылок означают, что Type & &&
становится Type &
для v
, ссылкой lvalue. Это именно то, что нам нужно назвать Call
. Вызов с помощью ссылки lvalue заставит копию точно так же, как если бы мы ее вызывали напрямую.
Если вы вызываете Fwd
с rvalue (то есть: временное выражение Type
или определенное Type&&
выражения), то T
будет выводиться как Type
. Правила ссылочного коллапса дают нам Type &&
, что вызывает движение / копию, что почти так же, как если бы мы назовем его напрямую (минус elision).
Если Call
берет свое значение с помощью ссылки lvalue, тогда его следует вызывать только тогда, когда пользователь использует параметры lvalue. Если это ссылка на const-lvalue, то она может быть вызвана чем угодно (lvalue, xvalue, prvalue).
Если вы вызываете Fwd
с lvalue, мы снова получаем Type&
как тип v
. Это будет связываться с ссылкой на константу без ссылки. Если мы называем его константным Lvalue, мы получаем const Type&
, которая будет связывать только с константным эталонным именующим аргументом в Call
.
При вызове Fwd
с xvalue, мы снова получаем Type&&
как тип v
. Это будет not позволяет вызывать функцию, которая принимает не const const lvalue, так как значение x не может связываться с ссылкой на константу lvalue. Он может привязываться к ссылке const lvalue, поэтому, если Call
использовал const&
, мы могли бы вызвать Fwd
с xvalue.
Если вы вызываете Fwd
с prvalue, мы снова получаем Type&&
, поэтому все работает по-прежнему. Вы не можете передать временное значение функции, которая принимает неконстантное значение lvalue, поэтому наша функция пересылки будет также подавляться в попытке сделать это.
Если Call
берет свое значение по ссылке rvalue, тогда его следует вызывать только тогда, когда пользователь использует параметры xvalue или rvalue.
Если вы вызываете Fwd
с lvalue, мы получаем Type&
. Это не будет связано с параметром ссылки rvalue, поэтому возникает ошибка компиляции. A const Type&
также не привязывается к параметру ссылки rvalue, поэтому он все равно не работает. И это именно то, что произойдет, если мы назовем Call
непосредственно с lvalue.
Если вы вызываете Fwd
с xvalue, мы получаем Type&&
, который работает (cv-qualification все еще имеет значение Конечно.
То же самое касается использования prvalue.
std :: forward сам использует правила сбрасывания ссылок аналогичным образом, чтобы передавать входящие значения rvalue в виде xvalues (значения возвращаемой функции, которые являются Type&&
, являются значениями x), а входящие значения lvalue как lvalues (возврат Type&
).
В случае различного количества пробелов до и после /
:
import re
re.sub("\s+/\s+", "_", "Peter North / John West")
# Peter North_John West
Вы можете использовать
a = "Peter North / John West"
import re
a = re.sub(' +/ +','_',a)
Любой номер пробела с косой чертой, за которым следует любое количество слешей, может быть заменен этим шаблоном.