![](/img/trans.png)
[英]Is there a way to pass a `constexpr` value into lambda so that it remains `constexpr` inside that lambda?
[英]Trying to pass a constexpr lambda and use it to explicitly specify returning type
我想使用一个函数并传递一个constexpr lambda
。 但是,只有让我通过auto
推导类型时,它才能成功编译。 通过-> std::array<event, l()>
显式提供类型似乎失败(第一个实例)。 为什么是这样?
template <typename Lambda_T>
constexpr static auto foo(Lambda_T l) -> std::array<event, l()> {
return {};
} // error
template <typename Lambda_T>
constexpr static auto foo(Lambda_T l) {
return std::array<event, (l())>{};
} // OK
template <typename Lambda_T>
constexpr static auto foo(Lambda_T l) -> decltype(l()) { return {}; }
// OK
请注意,lambda返回size_t
。
gcc错误,而没有调用(clang接受):
prog.cc:9:63: error: template argument 2 is invalid
9 | constexpr static auto foo(Lambda_T l) -> std::array<event, l()>
| ^
prog.cc:9:63: error: template argument 2 is invalid
prog.cc:9:63: error: template argument 2 is invalid
prog.cc:9:63: error: template argument 2 is invalid
prog.cc:9:42: error: invalid template-id
9 | constexpr static auto foo(Lambda_T l) -> std::array<event, l()>
| ^~~
prog.cc:9:61: error: use of parameter outside function body before '(' token
9 | constexpr static auto foo(Lambda_T l) -> std::array<event, l()>
| ^
prog.cc:9:23: error: deduced class type 'array' in function return type
9 | constexpr static auto foo(Lambda_T l) -> std::array<event, l()>
| ^~~
In file included from prog.cc:4:
/opt/wandbox/gcc-head/include/c++/9.0.1/array:94:12: note:
'template<class _Tp, long unsigned int _Nm> struct std::array' declared here
94 | struct array
| ^~~~~
prog.cc: In function 'int main()':
prog.cc:14:5: error: 'foo' was not declared in this scope
14 | foo([]() {return 3; });
| ^~~
constexpr函数的参数本身不是constexpr对象-因此,您不能在常量表达式中使用它们。 返回array
s的两个示例都是格式错误的,因为没有有效的调用。
要了解原因,请考虑以下废话示例:
struct Z { int i; constexpr int operator()() const { return i; }; };
template <int V> struct X { };
template <typename F> constexpr auto foo(F f) -> X<f()> { return {}; }
constexpr auto a = foo(Z{2});
constexpr auto b = foo(Z{3});
Z
具有constexpr
调用运算符,其格式正确:
constexpr auto c = Z{3}();
static_assert(c == 3);
但是,如果允许使用更早的用法,我们将有两个对foo<Z>
调用,这些调用必须返回不同的type 。 仅当实际值f
为模板参数时,才可以执行此操作。
注意,clang编译声明本身并不是编译器错误。 这是一类状况不佳的情况,不需要诊断。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.