Здесь можно сделать две вещи.И мне очень жаль, что нынешнее положение дел так неловко.
Самая прямая замена - это взять bind1st
и преобразовать его точно в bind
:
std::bind(&CGuild::LoadGuildData, this, std::placeholders::_1)
Или, если вы используете bind
регулярно, вы, вероятно, внесетезаполнители через using
в той или иной форме, так что это становится:
std::bind(&CGuild::LoadGuildData, this, _1)
Это на самом деле строго лучше, чем bind1st
, так как это передает свой аргумент, но bind1st
не будет.
Другая вещь, которую мы могли бы сделать, это лямбда.И здесь все зависит от того, что именно делает LoadGuildData
.Если он возвращает объект, и вас не волнует, как обязательно используется этот ограниченный вызываемый объект, вы можете просто написать:
[this](auto const& arg){ return LoadGuildData(arg); }
В большинстве случаев это будет работать.Но это не совсем то же самое, что выражение bind.Если LoadGuildData()
вернет что-то вроде int&
, выражение привязки вернет int&
, но эта версия вернет int
.Это может быть не важно.Это может быть не так.Но если это так, вы должны добавить, по крайней мере:
[this](auto const& arg) -> decltype(auto) { return LoadGuildData(arg); }
Это будет либо возвращать ссылочный тип, либо не ссылочный тип в зависимости от того, что на самом деле возвращает LoadGuildData
.
Теперь... аргумент, arg
, может потребоваться для модифицируемой ссылки, что требует
[this](auto&& arg) -> decltype(auto) { return LoadGuildData(arg); }
Но достаточно часто вам может понадобиться что-то большее.Возможно, вам придется использовать этот вызываемый в контексте, который должен проверить, если это вызываемый.Прямо сейчас, из-за правил, как работает эта проверка - все лямбды, которые я написал, будут утверждать, что они могут быть вызваны любым аргументом вообще.Независимо от того, что на самом деле LoadGuildData
.Но если это неправильный тип, вы получите серьезную ошибку компиляции.Несчастная.
Итак, что вам действительно нужно сделать, чтобы написать лямбду, которая будет иметь то же поведение, что и выражение связывания, которое я написал ранее:
[this](auto&& arg) -> decltype(LoadGuildData(std::forward<decltype(arg)>(arg))) {
return LoadGuildData(std::forward<decltype(arg)>(arg)));
}
На самом деле, это не совсем то же самое поведение,Эта лямбда на самом деле лучше в некоторых отношениях - потому что выражение привязки не сработало бы, если бы LoadGuildData
было шаблоном-функцией-членом или набором перегрузки или приняло аргумент по умолчанию - но лямбда работает во всех этих случаях.Вот почему так часто рекомендуют использовать лямбды - они всегда работают, они обычно являются лучшим решением, и иногда они являются единственным решением.
Но это огромный глоток, поэтому многие базы кода используют макросы.Как BOOST_HOF_RETURNS
:
#define FWD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
[this](auto&& arg) BOOST_HOF_RETURNS(LoadGuildData(FWD(arg)))
Все это говорит о том, что ... у нас не может быть хороших вещей.