我有一个std::tuple
填充从一个类型参数的类模板实例化的对象。现在我想在编译时从元组中获取具有指定类型参数的元素。这里是代码:不同的constexpr行为vs2015u2 vs gcc
template<typename Params, typename Descriptor>
struct IsParamsEqual;
template<typename Params1, typename Params2, ApiCommand::Value value>
struct IsParamsEqual<Params1, Descriptor<value, Params2>>
{
static constexpr bool v = std::is_same<Params1, Params2>::value;
};
template<typename Params, size_t I, typename... Args>
constexpr size_t getIndexByParamsHelper(const IndexSequence<I>&, const std::tuple<Args...> &)
{
return I;
}
template<typename Params, size_t I, size_t... Indexes, typename... Args>
constexpr size_t getIndexByParamsHelper(const IndexSequence<I, Indexes...> &,
const std::tuple<Args...> &tuple)
{
return IsParamsEqual<Params, typename std::tuple_element<I, std::tuple<Args...>>::type>::v ?
I : getIndexByParamsHelper<Params>(IndexSequence<Indexes...>(), tuple);
}
template<typename Params, size_t... Indexes, typename... Args>
constexpr size_t getIndexByParams(const IndexSequence<Indexes...> &seq,
const std::tuple<Args...> &tuple)
{
return getIndexByParamsHelper<Params>(seq, tuple);
}
template<typename Params, typename... Args>
constexpr auto getByParamsImpl(const std::tuple<Args...> &tuple)
{
constexpr size_t I = getIndexByParams<Params>(
typename MakeIndexSequence<sizeof...(Args)>::type(), tuple);
static_assert(std::is_same<typename std::remove_reference<decltype(
std::get<I>(tuple))>::type::paramType, Params>::value,
"Param not found");
return std::get<I>(tuple);
}
这编译好gcc 4.8.4而不是vs2015u2。该错误是在getByParamsImpl()
和它说:
错误C2131:表达式的结果不是一个常数
注:故障是由非恒定的参数或引用非恒定的符号
看到使用造成的'I'
显然,编译器认为getIndexByParams()
的返回值不是constexpr。
为什么,而且 - 更重要的是 - 如何解决这个问题?
是否删除静态断言有什么区别? –
唯一的区别是当static_assert被删除时,下一行的编译器扼流圈出现相同的错误。 – user6256186
好吧,基本上,'I'是一个constexpr,编译器认为'std :: get (tuple)'不是一个constexpr。至于“如何解决这个问题”,答案将会是,“编译器必须修复”。 –