Для тех, кто заинтересован, я действительно нашел решение, которое заключается в перемещении параметра this
в конец списка.Таким образом, мои std::invoke()
для функции-члена или стандартной статической функции работают одинаково:
f_function([this, f, args...]{ std::invoke(f, args..., this)(); })
Без этого, как упомянул Майлз Буднек, загрузке SFINAE потребуется знать, является ли f
функция-член или простая функция.
Проблема заключалась в том, что в некоторых случаях я создавал бы поток в функции-члене, а в других случаях создавал бы шаг из статической функции.
В случае функции-члена первым аргументом в списке args...
является this
вызывающего, и, очевидно, что this
не может быть перемещен как следующий параметр.
По сути, мойПервая попытка была сгенерирована следующим образом:
std::invoke(
&my_other_class::some_func, // correct
safe_thread::this, // wrong 'this' (i.e. safe_thread)
my_other_class::this, // 'this' for function, wrong location
...); // other parameters
Изменяя порядок в моем вызове, я теперь получаю правильное 'this' в правильном месте:
std::invoke(
&my_other_class::some_func, // correct
my_other_class::this, // 'this' for function, correct location
..., // other parameters
safe_thread::this); // 'this' to safe_thread
Очевидно, это означает, что у меня естьисправить сигнатуру вызываемых функций, но у меня все в порядке.
Как уже упоминалось tkausl, std::bind()
не требуется.Смотрите комментарии для деталей об этом.При этом std::invoke()
- это C ++ 17, поэтому, если вы все еще используете старую версию, вам, вероятно, придется придерживаться std::bind()
.