尝试传递constexpr lambda并使用它来显式指定返回类型 [英] Trying to pass a constexpr lambda and use it to explicitly specify returning type

查看:174
本文介绍了尝试传递constexpr lambda并使用它来显式指定返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用一个函数并传递一个constexpr lambda.但是,只有通过auto推导类型,它才能成功编译.通过-> std::array<event, l()>显式提供类型似乎失败(第一个实例).为什么会这样?

I would like to use a function and pass a constexpr lambda. However, it only compiles successfully if I let the type be deduced through auto. Explicitly giving the type through -> std::array<event, l()> seems to fail (the first instance). Why is this?

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.

Note that, the lambda returns a size_t.

gcc在没有呼叫的情况下出错(errors声接受):

gcc errors on this without a call (clang accepts it):

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的示例都格式错误,因为没有有效的调用.

Parameters to constexpr functions are not themselves constexpr objects - so you cannot use them in constant expressions. Both of your examples returning arrays are ill-formed because there is no valid call to them.

要了解原因,请考虑以下废话示例:

To understand why, consider this nonsense example:

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调用运算符,其格式正确:

Z has a constexpr call operator, and this is well-formed:

constexpr auto c = Z{3}();
static_assert(c == 3);

但是如果允许更早使用,我们将有两个调用foo<Z>的调用,这些调用必须返回不同类型.仅当实际值f是模板参数时,这种情况才会出现.

But if the earlier usage were allowed, we'd have two calls to foo<Z> that would have to return different types. This could only fly if the actual value f were the template parameter.

请注意,clang编译声明本身并不是编译器错误.这是一类状况不佳的情况,不需要诊断.

Note that clang compiling the declaration is not, in of itself, a compiler error. This is a class of situations that are ill-formed, no diagnostic required.

这篇关于尝试传递constexpr lambda并使用它来显式指定返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆