std::fuction 调用约定
std::fuction calling convention
我的代码中有观察者实现。它看起来像这样:
template <typename... Args>
class Event {
std::map<size_t, std::function<void(Args...)>> m_observers;
mutable std::mutex m_mutex;
public:
virtual ~Event() = default;
[[nodiscard]] size_t Register(const size_t& object_id, std::function<void(Args...)> observer) {
std::lock_guard<std::mutex> lk(m_mutex);
m_observers[object_id] = observer;
return object_id;
}
为了简洁起见,我没有在此处添加完整的 class 代码。
以及连接对象的代码:
class Object {
std::wstring m_name;
size_t m_id=0;
public:
Object() { GenerateID(); }
Object(std::wstring name) : m_name(name) { GenerateID(); }
virtual ~Object() = default;
size_t GetID() const { return m_id; }
template <class T, typename... Args>
size_t ObjectConnect(void(T::* callback_fn)(Args...args), Event<Args...>* obj_event);
template <typename... Args>
size_t ObjectConnect(std::function<void> fn(Args...args), Event<Args...>* obj_event);
private:
void GenerateID();
};
template<class T, typename... Args>
size_t Object::ObjectConnect(void(T::* callback_fn)(Args... args), Event<Args...>* obj_event) {
auto fn = [this, callback_fn](Args... args)->void {((static_cast<T*>(this))->*callback_fn)(args...); };
return obj_event->Register(m_id, fn);
}
template<typename ...Args>
inline size_t Object::ObjectConnect(std::function<void> fn(Args...args), Event<Args...>* obj_event)
{
return obj_event->Register(m_id, fn);
}
第一种 ObjectConnect
函数与子 classes 的成员函数完美配合。我添加了第二个重载以便能够传递带有附加参数的成员函数:
std::function<void(bool)> fn1 = [this, serverName](bool param) {this->OnServerConnection(serverName.toStdWString(), param); };
ObjectConnect(fn1, Refactoring::Backend::GetManagerByName(serverName.toStdWString())->GetConnectionEvent());
遗憾的是它给了我下一个错误:
Error C2784 'size_t Design::Object::ObjectConnect(std::function<void> (__cdecl *)(Args...),Design::Event<Args...> *)': could not deduce template argument for 'std::function<void> (__cdecl *)(Args...)' from 'std::function<void (bool)>'
从错误消息来看,它似乎与调用约定有关,但我不知道该怎么做,谷歌搜索也没有给我任何线索。
这与调用约定无关:所有成员函数在 C++ 中具有相同的调用约定(有时称为“thiscall”),std::function<T>::operator()
是一个成员函数。
相反,问题是你的函数原型是一个 std::function<T>
是不正确的。签名进入模板参数列表 ,如下所示:
template <typename... Args>
size_t ObjectConnect(std::function<void(Args...)> fn, Event<Args...>* obj_event);
我的代码中有观察者实现。它看起来像这样:
template <typename... Args>
class Event {
std::map<size_t, std::function<void(Args...)>> m_observers;
mutable std::mutex m_mutex;
public:
virtual ~Event() = default;
[[nodiscard]] size_t Register(const size_t& object_id, std::function<void(Args...)> observer) {
std::lock_guard<std::mutex> lk(m_mutex);
m_observers[object_id] = observer;
return object_id;
}
为了简洁起见,我没有在此处添加完整的 class 代码。 以及连接对象的代码:
class Object {
std::wstring m_name;
size_t m_id=0;
public:
Object() { GenerateID(); }
Object(std::wstring name) : m_name(name) { GenerateID(); }
virtual ~Object() = default;
size_t GetID() const { return m_id; }
template <class T, typename... Args>
size_t ObjectConnect(void(T::* callback_fn)(Args...args), Event<Args...>* obj_event);
template <typename... Args>
size_t ObjectConnect(std::function<void> fn(Args...args), Event<Args...>* obj_event);
private:
void GenerateID();
};
template<class T, typename... Args>
size_t Object::ObjectConnect(void(T::* callback_fn)(Args... args), Event<Args...>* obj_event) {
auto fn = [this, callback_fn](Args... args)->void {((static_cast<T*>(this))->*callback_fn)(args...); };
return obj_event->Register(m_id, fn);
}
template<typename ...Args>
inline size_t Object::ObjectConnect(std::function<void> fn(Args...args), Event<Args...>* obj_event)
{
return obj_event->Register(m_id, fn);
}
第一种 ObjectConnect
函数与子 classes 的成员函数完美配合。我添加了第二个重载以便能够传递带有附加参数的成员函数:
std::function<void(bool)> fn1 = [this, serverName](bool param) {this->OnServerConnection(serverName.toStdWString(), param); };
ObjectConnect(fn1, Refactoring::Backend::GetManagerByName(serverName.toStdWString())->GetConnectionEvent());
遗憾的是它给了我下一个错误:
Error C2784 'size_t Design::Object::ObjectConnect(std::function<void> (__cdecl *)(Args...),Design::Event<Args...> *)': could not deduce template argument for 'std::function<void> (__cdecl *)(Args...)' from 'std::function<void (bool)>'
从错误消息来看,它似乎与调用约定有关,但我不知道该怎么做,谷歌搜索也没有给我任何线索。
这与调用约定无关:所有成员函数在 C++ 中具有相同的调用约定(有时称为“thiscall”),std::function<T>::operator()
是一个成员函数。
相反,问题是你的函数原型是一个 std::function<T>
是不正确的。签名进入模板参数列表 ,如下所示:
template <typename... Args>
size_t ObjectConnect(std::function<void(Args...)> fn, Event<Args...>* obj_event);