Кажется, проблема в том, что std::bind
внутренне передает оцененные результаты Callable
(это на самом деле std::bind<>
тип) объект c
при повторной передаче его во второй разздесь:
part2(std::bind(&Quux::part3<Callable>, this, 3, c))
Не передается безоценочная версия объекта std::bind
, как вы предполагаете.
Таким образом, поскольку ваша функция f
возвращает тип void
, результат выражения c
внутренне передается как тип void
, а не как объект безошибочной вызываемой функции.Таким образом, когда вы пытаетесь вызвать Callable
объект c
в Quux::part2
, который, в свою очередь, пытается оценить вызов c
в Quux::part3
, он не может передать вызываемый объект в качестве второго аргумента Quux::part3
, поскольку тип, который он передает, на самом деле является типом void
, а не вызываемым типом.
Для получения дополнительной информации см. здесь: http://en.cppreference.com/w/cpp/utility/functional/bind
Обратите особое внимание на то, что:
Если std::is_bind_expression<T>::value==true
(т. Е. Другое подвыражение std::bind()
было использовано в качестве аргумента при первоначальном вызове bind
), то это подвыражение bind вызывается немедленно и его result передается в функцию.
Если вы хотите отложить оценку, чтобы она происходила тогда, когда вы этого хотите, а не когда вы передаете подвыражение std::bind
, вам придется посмотретьдля другого метода, такого как лямбда, или std::function<>
объект, функтор или некоторый другой тип объекта класса, который может быть вызван и может хранить состояние, которое может быть оценено позже.