2016-03-28 68 views
0

我试图键入别名std::bitset类,其中模板参数N是使用constexpr函数计算的。但是,这种方法似乎正在陷入困境。调用位集模板参数的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' 

感谢您的帮助。

+1

您的代码使用Visual Studio 2015 Update 1和webcompiler.cloudapp.net编译。 –

+0

这很奇怪。我也运行Visual Studio 2015(特别是,版本14.0.23107.0)。不过,我不确定这是不是“更新1”。这很可能不会,假设14.1 ...将对应更新1. –

+0

我相信这是RTM。我的版本是14.0.24720.00。在更新1中修复了constexpr错误[很多](https://blogs.msdn.microsoft.com/vcblog/2015/12/02/constexpr-in-vs2015-update-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在ComponentCount()TagCount()函数调用中找到了错误function call must have a constant value in a constant expression,并用红色突出显示它们。显然,编译器无法查看与常量表达式包含在同一个结构中的静态constexpr函数?奇怪的。它可能是在定义常量表达式之前尝试执行类型别名。

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

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

// ... 

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

然而,这种方法不适用于非模板结构的工作。在这种情况下查看我的其他StackOverflow post不同的方法。

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它应该工作)。