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

时间:2018-06-07 21:51:24

标签: c++ templates

考虑以下受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;

基本上,我正在获取模板类型参数包,并试图提取位于此包中偶数位置的所有类型的常见类型。

上面的代码适用于 gcc 8.1 clang 6.0 ,但是最新的 MSVC 版本失败并出现以下错误:

  

错误C2971:'std :: tuple_element_t':模板参数'_Index':'I':具有非静态存储持续时间的变量不能用作非类型参数

我是否错过了这里的任何重要细节,还是只是另一个 MSVC 错误?

Godbolt link

1 个答案:

答案 0 :(得分:3)

这是一个错误,visual有一些别名问题,无需typename。这是type_at

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

解决方法是使用别名替换别名type_at

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