我正在使用MSVS c ++ 17,下面的代码无法编译:

#include <type_traits>
#include <tuple>

using namespace std;

template <size_t Size, class Pred, size_t idx=0, size_t... pass>
constexpr auto makeIndices(const Pred &pred)
{
    if constexpr(idx >= Size)
    {
        return index_sequence<pass...>();
    }
    else if constexpr(pred(integral_constant<size_t, idx>()))  //<-- HERE!!!!
    {
        return makeIndices<Size, Pred, idx+1, pass..., idx>(pred);
    }
    else
    {
        return makeIndices<Size, Pred, idx+1, pass...>(pred);
    }
}

template <class Tuple, size_t... I>
constexpr auto extract(Tuple&&v, index_sequence<I...> = index_sequence<I...>())
{
    return tuple<tuple_element_t<I, decay_t<Tuple>>...>(get<I>(forward<Tuple>(v))...);
}

template <class Tuple, class Pred>
constexpr auto extract(Tuple&&v, const Pred &pred)
{
    return extract(std::forward<Tuple>(v), makeIndices<tuple_size_v<decay_t<Tuple>>>(pred));
}

template <class Target, class Tuple>
constexpr auto del(Tuple &&v)
{
    return extract(std::forward<Tuple>(v), [](auto idx)
    {
        return !is_same_v<Target, tuple_element_t<idx(), decay_t<Tuple>>>;
    });
}

void MyFunc()
{
    auto src = make_tuple("one", 1, "two", 2, "three", 3, "fourty", 40);
    del<int>(src);
}


在函数“ makeIndices”中,我标记了出现错误的位置。它看起来像:


  错误C2131:表达式未求值为常数
  
  注意:失败是由于在其生命周期之外读取变量导致的
  
  注意:请参阅“ pred”的用法
  
  注意:请参见功能模板参考
  实例化'auto makeIndices (const Pred&)'被
  编译...


上面的代码可以在GCC(Link)上编译并正常工作。

但是,如何为MSVS修复它?

最佳答案

根据评论,MSVC是正确的拒绝。 pred是一个引用,并且在函数体内,尚不清楚对象pred所指的是什么。因此,常量表达式中不允许使用pred(...),即使实际上根本不使用pred也是如此。

但是,您可以做的是按值传递pred(将const Pred &pred更改为Pred pred)。然后,pred肯定会引用一个有效的对象,这足以使MSVC接受该调用。

关于c++ - 使用lambda编译constexpr时,MSVS2017错误“表达式的计算结果不为常数”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50786104/

10-11 16:04