为bitset模板参数

时间:2016-03-28 05:00:03

标签: c++ templates visual-studio-2015 constexpr bitset

我正在尝试使用constexpr函数键入std::bitset类的别名,其中模板参数N是使用constexpr函数计算的。然而,这种方法似乎陷入困境。

目前代码如下:

static constexpr std::size_t ComponentCount() noexcept {
    return 3U;
}

static constexpr std::size_t TagCount() noexcept {
    return 5U;
}

using Bitset = std::bitset<ComponentCount() + TagCount()>;

我收到的错误如下:

1>error C2975: '_Bits': invalid template argument for 'std::bitset', expected compile-time constant expression
1>  note: see declaration of '_Bits'

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

如@MattWeber的评论中所示,使用当前的webcompiler.cloudapp.net和编译器版本19.00.23720.0(2016年1月20日建立)这个小型测试程序使用您的代码

int main()
{
   cout << Bitset{}.size() << "\n";
}

输出8.所以只需获取最新的Visual Studio并检查编译器版本(如果它大于19.00.23720.0它应该工作)。

答案 1 :(得分:0)

事实证明,我在原始问题中没有包含足够的背景信息。问题最终变得更加微妙。

这里更准确地表示了我的代码的外观:

template
<
    typename ComponentList,
    typename TagList,
    typename SignatureList
>
struct Settings {
    // ...

    static constexpr std::size_t ComponentCount() noexcept {
        return 3U;
    }

    static constexpr std::size_t TagCount() noexcept {
        return 5U;
    }

    // ...

    using Bitset = std::bitset<ComponentCount() + TagCount()>;

    // ...
};

这种方法对我来说似乎没问题,并没有向我提供任何编译器警告或任何东西。只是原始问题中提到的编译器错误。

然而,当我为了更准确地隔离问题而进一步简化问题时,我最终得到了这个:

struct Settings {
    static constexpr std::size_t ComponentCount() noexcept {
        return 3U;
    }

    static constexpr std::size_t TagCount() noexcept {
        return 5U;
    }

    using Bitset = std::bitset<ComponentCount() + TagCount()>;
};

执行此简化后(或更具体地说,在删除模板参数后),VS2015在function call must have a constant value in a constant expressionComponentCount()函数调用上发现错误TagCount(),并突出显示它们红色的。显然,编译器无法查看与常量表达式包含在同一结构中的静态constexpr函数?奇怪的。它可能在定义const表达式之前尝试进行类型别名。

模板化结构的解决方案如下:

using ThisType = Settings<ComponentList, TagList, SignatureList>;

// ...

using Bitset = std::bitset<ThisType::ComponentCount() + ThisType::TagCount()>;

但是,这种方法不适用于非模板化结构。在这种情况下,请参阅我的其他StackOverflow post了解不同的方法。