【发布时间】:2016-08-20 06:07:26
【问题描述】:
我有一个std::tuple,其中填充了从具有一个类型参数的类模板实例化的对象。现在我想在编译时从我的元组中获取一个具有指定类型参数的元素。代码如下:
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:表达式未计算为常量
注意:失败是由非常量参数或对非常量符号的引用引起的
查看“我”的用法
很明显,编译器认为getIndexByParams()返回值不是constexpr。
为什么,以及 - 更重要的是 - 如何解决这个问题?
【问题讨论】:
-
删除静态断言有什么不同吗?
-
唯一的区别是当 static_assert 被删除时,编译器在下一行出现同样的错误。
-
好的,所以,基本上,
I是一个 constexpr,编译器认为std::get<I>(tuple)不是一个 constexpr。至于“如何解决这个问题”,答案几乎是“必须修复编译器”。
标签: c++ c++11 gcc visual-studio-2015 variadic-templates