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

如何在MSVC中正确使用BOOST_HOF_LIFT与BOOST_HOF_LIFT_CLASS宏

你遇到的两个错误分别来自MSVC的编译器缺陷,和对BOOST_HOF_LIFT_CLASS宏的用法错误,对应的解决方案如下:

1. 替换模板变量为模板函数绕开MSVC缺陷

BOOST_HOF_LIFT本质是返回一个函数对象的宏,你之前用模板变量存储返回值的写法触发了MSVC对模板变量内lambda表达式的实例化bug,改为用模板函数返回BOOST_HOF_LIFT的结果即可兼容MSVC:

#include <boost/hof.hpp>
#include <tuple>
#include <cassert>

template<int N>
constexpr auto getNth_a() {
    return BOOST_HOF_LIFT(std::get<N>);
}

int main() {
    std::tuple<int,int> t{1,2};
    // 调用时多写一对括号即可
    assert(getNth_a<0>()(t) == 1);
}

这个写法在GCC、Clang、MSVC下都可以正常编译运行。

2. 修正BOOST_HOF_LIFT_CLASS的用法

BOOST_HOF_LIFT_CLASS的作用是直接生成一个非模板类,不能直接在模板作用域内用它生成依赖模板参数的类型,必须把它嵌套到模板结构体内部使用:

#include <boost/hof.hpp>
#include <tuple>
#include <cassert>

template<int N>
struct getNth_b {
    // 把LIFT_CLASS生成的类放到模板结构体内部,作为依赖类型
    BOOST_HOF_LIFT_CLASS(type, std::get<N>);
};

// 可选:搭配别名模板简化调用,避免每次写typename
template<int N>
using getNth_b_t = typename getNth_b<N>::type;

int main() {
    std::tuple<int,int> t{1,2};
    // 基础用法
    assert(typename getNth_b<0>::type()(t) == 1);
    // 用别名模板的简化用法
    assert(getNth_b_t<0>()(t) == 1);
}

替代方案(C++20及以上)

如果你的项目可以使用C++20,完全可以不用Boost.HOF的宏,直接用模板lambda实现同样的功能,兼容性更好:

#include <tuple>
#include <cassert>

template<int N>
constexpr auto getNth = []<typename T>(T&& tuple) noexcept(noexcept(std::get<N>(std::forward<T>(tuple)))) -> decltype(auto) {
    return std::get<N>(std::forward<T>(tuple));
};

int main() {
    std::tuple<int,int> t{1,2};
    assert(getNth<0>(t) == 1);
}

这个写法在MSVC、GCC、Clang下都可以直接用getNth<0>(t)的方式调用,没有兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 02:09:02