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

如何在继承可变参数模板类型列表的类方法中调用成员类方法?

问题

我希望实现一个类,能够让一系列类按顺序调用各自的decode/encode方法,为此编写了如下模板类代码:

/// This class manages the decoding/encoding of a sequence of binary fields.
template <typename Derived, typename... Fields >
struct BinarySequence : Fields...
{
    using Super = BinarySequence;

    bool decode(const char* buffer, size_t& length)
    {
        return true && Fields...::decode(buffer, length);
    }

    bool encode(char* buffer, size_t& length)
    {
        return true && Fields...::encode(buffer, length);
    }
};

但Fields...::decode(buffer, length)的调用方式不正确。例如当我使用BinarySequence< MessageType, MessageSender, MessageTimeStamp >时,希望decode方法能实现如下逻辑:

bool decode(const char* buffer, size_t& length)
{
    return MessageType::decode(buffer, length) && MessageSender::decode(buffer, length) && MessageTimeStamp::decode(buffer, length);
}

请问正确的实现方式是什么?我使用的是Visual Studio 2017。

解决方案

方式1:C++17折叠表达式(VS2017 15.5及以上版本支持)

原代码的问题在于折叠表达式的语法错误,正确的&&折叠表达式需要用括号包裹以明确展开规则。修改后的代码如下:

/// This class manages the decoding/encoding of a sequence of binary fields.
template <typename Derived, typename... Fields >
struct BinarySequence : Fields...
{
    using Super = BinarySequence;

    bool decode(const char* buffer, size_t& length)
    {
        // 按模板参数顺序依次调用每个Field的decode,保留&&的短路求值特性
        return (true && ... && Fields::decode(buffer, length));
    }

    bool encode(char* buffer, size_t& length)
    {
        return (true && ... && Fields::encode(buffer, length));
    }
};

编译器会将(true && ... && Fields::decode(...))展开为你期望的链式&&调用,并且只要有一个decode返回false,后续调用会被短路跳过。

方式2:初始化列表兼容写法(适配VS2017早期版本)

如果你的VS2017版本较早,对折叠表达式支持不完善,可以使用初始化列表的方式强制按顺序调用:

template <typename Derived, typename... Fields >
struct BinarySequence : Fields...
{
    using Super = BinarySequence;

    bool decode(const char* buffer, size_t& length)
    {
        bool result = true;
        // 利用初始化列表的顺序求值特性,依次执行每个Field的decode
        auto dummy = { (result = result && Fields::decode(buffer, length), 0)... };
        (void)dummy; // 消除未使用变量的编译警告
        return result;
    }

    bool encode(char* buffer, size_t& length)
    {
        bool result = true;
        auto dummy = { (result = result && Fields::encode(buffer, length), 0)... };
        (void)dummy;
        return result;
    }
};

这种写法基于C++11的初始化列表特性,VS2017完全支持。初始化列表会严格按照模板参数顺序执行每个元素的表达式,同时借助&&的短路特性,当result变为false时,后续的decode/encode调用会被跳过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:35:23