Visual Studio 2015 在 constexpr 中使用 lambda
Posted
技术标签:
【中文标题】Visual Studio 2015 在 constexpr 中使用 lambda【英文标题】:Visual Studio 2015 using a lambda in constexpr 【发布时间】: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(哦,对了,它告诉我“您无权提交此连接的反馈。”)
【参考方案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<?>
的变量,其中?
是在其int
参数上加1 的lambda 类型,但没有办法(在定义的行为)来创建或运行该类型的 lambda?
@Yakk 这是使用return reinterpret_cast<const F&>(*this)(std::forward<Ts>(xs)...);
编写Static Lambdas: Initializing lambdas at compile time 的保罗。它不能保证工作,这是肯定的,但它确实有一个static_assert
,它有望检测到任何有问题的实现。在许多实现中,行为将被定义:对于具有简单初始化的类型(诚然,这并不完全是检查的内容),调用实例成员而不实际构造该类型的实例是有效的。
@hvd 有什么比 add_one
更好的功能?
@Yakk Lambdas 允许将参数指定为auto
,函数还没有。不过,使用int
,我想我同意没有任何好处。以上是关于Visual Studio 2015 在 constexpr 中使用 lambda的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 2015 中打开 Visual Studio 2017 项目
Intel parallel studio 2017 集成在visual studio 2013 中,现在如何集成到visual studio 2015