如何推导类方法中的模板类型并定义对应类型的类成员变量?
问题:推导Qt QProperty::onValueChanged返回类型并作为类成员存储
Qt的QProperty<T>模板类提供了onValueChanged模板方法,其签名为:
template <typename Functor> QPropertyChangeHandler<Functor> QProperty::onValueChanged(Functor f)
我需要推导该方法的返回类型,以便将返回值作为类成员存储——std::any无法使用,因为QPropertyChangeHandler<Functor>不支持拷贝构造。这个返回类型是QPropertyChangeHandler<Functor>,一个以函数对象类型为模板参数的模板类。
我最初的思路是这样的,但编译失败:
class Foo { Foo(QProperty<uint> &property) { auto handler = property.onValueChanged( [this, &property] { /* 业务逻辑 */ }); using Handler = decltype(handler); // 这里推导的类型在成员定义处不可见 // m_handler = std::move(handler); } Handler m_handler; // 编译错误:Handler在此作用域未定义 };
下面是另一次失败的尝试:
class Foo { // 尝试通过declval推导返回类型,但无法匹配实际lambda的签名 using Handler = decltype(std::declval<QProperty<uint>>().onValueChanged([]{})); Handler m_handler; Foo(QProperty<uint> &property): m_handler{ // 编译错误:无匹配的构造函数 property.onValueChanged([this, &property] { /* 业务逻辑 */ }) }{ } };
可行解决方案
方案1:将类改为模板类
把lambda的类型作为Foo的模板参数,这样就能直接定义成员类型:
template<typename Func> class Foo { public: Foo(QProperty<uint>& property, Func&& func) : m_handler(property.onValueChanged(std::forward<Func>(func))) {} private: QPropertyChangeHandler<Func> m_handler; }; // 使用示例 QProperty<uint> my_prop; auto foo_instance = Foo{my_prop, [&my_prop](){ /* 处理值变化逻辑 */ }};
方案2:用std::function做类型擦除
如果不想让Foo成为模板类,可以将lambda包装到std::function<void()>中,固定QPropertyChangeHandler的模板参数:
class Foo { public: Foo(QProperty<uint>& property) : m_handler(property.onValueChanged( std::function<void()>([this, &property] { /* 处理值变化逻辑 */ }) )) {} private: QPropertyChangeHandler<std::function<void()>> m_handler; };
方案3:C++20自动推导成员类型
如果编译器支持C++20,可以直接用auto声明成员变量,让编译器自动推导类型:
class Foo { public: Foo(QProperty<uint>& property) : m_handler(property.onValueChanged([this, &property] { /* 处理值变化逻辑 */ })) {} private: auto m_handler; // C++20支持自动推导非静态数据成员类型 };
内容的提问来源于stack exchange,提问作者Jackoo
相关产品推荐
相关产品推荐

