代码之家  ›  专栏  ›  技术社区  ›  Edgar Rokjān

msvc:具有非静态存储持续时间的变量不能用作非类型参数

  •  1
  • Edgar Rokjān  · 技术社区  · 6 年前

    考虑以下代码 this talk :

    template<typename, typename...>
    struct even_common_type_helper_impl;
    
    template<std::size_t... Is, typename... Ts>
    struct even_common_type_helper_impl<std::index_sequence<Is...>, Ts...>
    {
        template<std::size_t I>
        using type_at = std::tuple_element_t<I, std::tuple<Ts...>>;
    
        using even_common_type = std::common_type_t<type_at<2 * Is>...>;
    };
    
    template<typename... Ts>
    using even_common_type_helper =
        even_common_type_helper_impl<std::make_index_sequence<sizeof...(Ts) / 2>, Ts...>;
    
    template<typename... Ts>
    using even_common_type = typename even_common_type_helper<Ts...>::even_common_type;
    

    基本上,我得到了一个模板类型参数包,并试图提取位于该包中偶数位置的所有类型的公共类型。

    上面的代码与 海湾合作委员会8.1 铿锵6 ,但最近一次失败 MSVC 出现以下错误的版本:

    错误C271::STD:tupEyEntEntLyt:模板参数“x索引”:“i”:具有非静态存储持续时间的变量不能用作非类型参数

    我是错过了一些重要的细节还是只是另外一个 MSVC 缺陷?

    Godbolt link

    1 回复  |  直到 6 年前
        1
  •  3
  •   Jarod42    6 年前

    这是一个bug,visual与alias有一些问题,这就消除了 typename . 这里的情况是 type_at

    template<std::size_t I>
    using type_at = std::tuple_element_t<I, std::tuple<Ts...>>;
    

    解决方法是替换alias Type 使用它的别名:

    using even_common_type = std::common_type_t<
        type_at<(2u * Is)>
    ...>;
    

    通过

    using even_common_type = std::common_type_t<
        typename std::tuple_element<2 * Is, std::tuple<Ts...>>::type
    ...>;
    

    Demo