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

C++带指定类型的非类型模板模板的正确语法与参数简化

简化std::optional成员指针模板参数的可行方案

这种简化是可行的,在C++17及以上标准中,利用自动推导的非类型模板参数即可实现仅传递成员指针、让编译器自动推导所属类C和optional内部类型T的效果。

正确实现代码

#include <optional>
#include <type_traits>

class A
{
public:
  std::optional<int> i;
};

// 核心:用auto作为非类型模板参数,自动推导成员指针的类型
template <auto OptionalMemberPtr>
class OptionalHolder
{
    // 从成员指针推导所属类C
    using ContainingClass = std::remove_pointer_t<std::decay_t<decltype(OptionalMemberPtr)>>;
    // 推导optional的具体类型
    using OptionalType = std::remove_reference_t<decltype(*OptionalMemberPtr)>;
    // 推导optional内部的T类型
    using ValueType = typename OptionalType::value_type;

public:
    void doStuff(ContainingClass& c) {
        // 示例操作:访问成员并判断是否有值
        if (c.*OptionalMemberPtr) {
            // 可直接操作*c.*OptionalMemberPtr,如输出值
            // std::cout << *c.*OptionalMemberPtr << std::endl;
        }
    }
};

// 简化使用:仅需传递成员指针,无需显式指定C和T
using OH = OptionalHolder<&A::i>;

为什么你之前的写法无法编译

你尝试的template<class T> std::optional<T> C::*这类写法属于误用模板模板参数:模板模板参数是用来匹配模板本身(比如template<typename> class Opt),而std::optional<T> C::*是一个具体的成员指针类型,并非模板,因此编译器无法识别这种语法。

兼容性说明

如果需要兼容C17之前的标准,可以通过decltype结合辅助模板实现推导,但代码会更繁琐。C17的auto非类型模板参数是最简洁的解决方案。

内容的提问来源于stack exchange,提问作者Hugal31

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:37:30