【问题标题】:Visual Studio 2015 using a lambda in constexprVisual Studio 2015 在 constexpr 中使用 lambda
【发布时间】:2015-07-29 21:20:16
【问题描述】:

所以在最新的 Visual Studio 2015 中,以下代码似乎不再起作用:

template<class F>
struct wrapper
{
    constexpr wrapper()
    {}
};

template<typename T> 
constexpr typename std::remove_reference<T>::type *addr(T&& t) 
{ 
    return &t; 
}

template<class F>
constexpr wrapper<F> wrap(F*)
{
    return wrapper<F>();
}


const constexpr auto add_one = wrap(true ? nullptr : addr([](int x)
{
    return x + 1;
}));

Visual Studio 报告回illegal initialization of 'constexpr' entity with a non-constant expression。这曾经在候选版本中工作,但最新版本似乎不再工作(我正在使用版本14.0.23107.0)。这应该有效(它在 clang 和 gcc 中都有效)。

很遗憾,Microsoft 不允许我报告错误。那么有人知道解决方法吗?

【问题讨论】:

  • 问题不完全是你所说的。将 true ? nullptr : addr(...) 更改为 true ? (void *) 0 : addr(...) 并被接受,即使它使用 lambda。 (我知道这会阻止 add_one 拥有您想要的类型,我不建议将其作为替代品。)
  • 如果您想报告错误,请尝试connect.microsoft.com/VisualStudio(哦,对了,它告诉我“您无权提交此连接的反馈。”)

标签: c++ visual-studio c++11 constexpr


【解决方案1】:

好的,正如@hvd 所指出的那样,Visual Studio 似乎在使用constexpr 转换指针时存在问题。我发现一种解决方法,我可以这样做:

template<class F>
struct wrapper
{
    constexpr wrapper()
    {}
};

struct wrapper_deduce
{
    constexpr wrapper_deduce()
    {}
    template<class T>
    constexpr operator wrapper<T>() const
    {
        return wrapper<T>();
    }
};


template<class F>
constexpr wrapper<F> wrap_direct(const F&)
{
    return wrapper<F>();
}


const constexpr auto add_one = true ? wrapper_deduce() : wrap_direct([](int x)
{
    return x + 1;
});

【讨论】:

  • 所以,你想要一个constexpr 类型为wrapper&lt;?&gt; 的变量,其中? 是在其int 参数上加1 的lambda 类型,但没有办法(在定义的行为)来创建或运行该类型的 lambda?
  • @Yakk 这是使用return reinterpret_cast&lt;const F&amp;&gt;(*this)(std::forward&lt;Ts&gt;(xs)...); 编写Static Lambdas: Initializing lambdas at compile time 的保罗。它不能保证工作,这是肯定的,但它确实有一个static_assert,它有望检测到任何有问题的实现。在许多实现中,行为将被定义:对于具有简单初始化的类型(诚然,这并不完全是检查的内容),调用实例成员而不实际构造该类型的实例是有效的。
  • @hvd 有什么比 add_one 更好的功能?
  • @Yakk Lambdas 允许将参数指定为auto,函数还没有。不过,使用int,我想我同意没有任何好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多