You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何推导类方法中的模板类型并定义对应类型的类成员变量?

问题:推导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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 05:45:02