#c #c 11 #std-function
Вопрос:
Получение ошибки ниже для кода, приведенного ниже. Попытка создать 3 функции std::внутри класса шаблона, а затем инициализировать их различными функциями из разных классов.
Почему происходит эта ошибка? Что не так с нижеприведенным кодом?
template <typename T>
class CFuntion {
public:
std::function<void()> callback_1;
std::function<void()> callback_2;
std::function<void()> callback_3;
template <typename A, typename B, typename C>
CFuntion(A cb1, B cb2, C cb3)
: callback_1(cb1), callback_2(cb2), callback_3(cb3)
{ }
};
class Impl1 {
public:
void do_something1() {
cout << "Inside Impl1 do_something1" << endl;
}
void do_something2() {
cout << "Inside Impl1 do_something2" << endl;
}
};
class Impl2 {
public:
void do_something1() {
cout << "Inside Impl2 do_something1" << endl;
}
void do_something2() {
cout << "Inside Impl2 do_something2" << endl;
}
};
class Impl3 {
public:
void do_something1() {
cout << "Inside Impl3 do_something1" << endl;
}
void do_something2() {
cout << "Inside Impl3 do_something2" << endl;
}
};
int main()
{
unique_ptr<CFuntion<void>> ptr1 = make_unique<CFuntion<void>>(std::bind(amp;Impl1::do_something1, amp;Impl2::do_something1,
amp;Impl3::do_something2));
ptr1->callback_1();
ptr1->callback_2();
ptr1->callback_3();
system("pause");
return 0;
}
Комментарии:
1.
CFunction<void>
имеет два конструктора — указанный вами конструктор, который принимает три аргумента, и конструктор копирования, который принимаетconst CFunction<void>amp;
. Вы пытаетесь передать один аргумент, который является выражением привязки,std::bind(x, y, z)
. Ни один из конструкторов не может принять этот аргумент.2. Кроме того, ваше выражение привязки не имеет никакого смысла: вы просите его вызвать
Impl1::do_something1
с двумя аргументамиamp;Impl2::do_something1
иamp;Impl3::do_something2
. Вы, вероятно, имели в виду три отдельныхbind
звонка. Но простойstd::bind(amp;Impl1::do_something1)
тоже не будет работать —do_something1
это нестатическая функция-член, и для ее вызова требуется экземплярImpl1
. В общем, непонятно, чего вы пытаетесь достичь.3. @IgorTandetnik — я также пытался с этим кодом, но это тоже не удается, unique_ptr<CFuntion<void><void>> ptr1 = make_unique<void>><CFuntion<void><void>>(std::привязка(amp;Impl1::do_something1), std::привязка(amp;Impl2::do_something1), std::привязка(amp;Impl3::do_something2));
4. Мой второй комментарий касается этого.
Ответ №1:
Посмотрите на эту часть:
unique_ptr<CFuntion<void>> ptr1 = make_unique<CFuntion<void>(std::bind(amp;Impl1::do_something1, amp;Impl2::do_something1, amp;Impl3::do_something2));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Здесь вы передаете только один объект своему CFunction<void>
конструктору. То, что вам нужно, может быть, это:
// You need to pass temporary objects to 'std::bind()' to bind non-static member functions
Impl1 obj1;
Impl2 obj2;
Impl3 obj3;
std::unique_ptr<CFuntion<void>> ptr1 = std::make_unique<CFuntion<void>>(std::bind(amp;Impl1::do_something1, obj1), std::bind(amp;Impl2::do_something1, obj2), std::bind(amp;Impl3::do_something2, obj3));
Или, посмотрев на ваши Impl1
Impl2
Impl3
классы и , кажется, вы могли бы просто создать их методы-члены static
(поскольку ни один из этих трех классов, похоже, не нуждается в каком-либо различии между их объектами или имеет какие-либо переменные экземпляра для доступа/изменения).:
class Impl1 {
public:
static void do_something1() {
cout << "Inside Impl1 do_something1" << endl;
}
static void do_something2() {
cout << "Inside Impl1 do_something2" << endl;
}
};
class Impl2 {
public:
static void do_something1() {
cout << "Inside Impl2 do_something1" << endl;
}
static void do_something2() {
cout << "Inside Impl2 do_something2" << endl;
}
};
class Impl3 {
public:
static void do_something1() {
cout << "Inside Impl3 do_something1" << endl;
}
static void do_something2() {
cout << "Inside Impl3 do_something2" << endl;
}
};
Таким образом, вам просто нужно сделать это, что, по-видимому, и есть то, что вы хотите сделать:
std::unique_ptr<CFuntion<void>> ptr1 = std::make_unique<CFuntion<void>>(std::bind(amp;Impl1::do_something1), std::bind(amp;Impl2::do_something1), std::bind(amp;Impl3::do_something2));
Комментарии:
1. Спасибо за ответ. Однако один вопрос: если мне нужно передать аргументы функциям do_something, как это можно сделать?
2. Вы можете поместить значения аргументов в
std::bind
std::bind(amp;Impl1::do_something1, 12, "abc", 'a')
, и т.д. Кроме того, страницаstd::bind()
cppreference может быть полезна для вас .