简体   繁体   English

尝试传递constexpr lambda并使用它来显式指定返回类型

[英]Trying to pass a constexpr lambda and use it to explicitly specify returning type

I would like to use a function and pass a constexpr lambda . 我想使用一个函数并传递一个constexpr lambda However, it only compiles successfully if I let the type be deduced through auto . 但是,只有让我通过auto推导类型时,它才能成功编译。 Explicitly giving the type through -> std::array<event, l()> seems to fail (the first instance). 通过-> std::array<event, l()>显式提供类型似乎失败(第一个实例)。 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

Note that, the lambda returns a size_t . 请注意,lambda返回size_t

gcc errors on this without a call (clang accepts it): 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; });
      |     ^~~

Parameters to constexpr functions are not themselves constexpr objects - so you cannot use them in constant expressions. constexpr函数的参数本身不是constexpr对象-因此,您不能在常量表达式中使用它们。 Both of your examples returning array s are ill-formed because there is no valid call to them. 返回array s的两个示例都是格式错误的,因为没有有效的调用。

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 has a constexpr call operator, and this is well-formed: Z具有constexpr调用运算符,其格式正确:

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

But if the earlier usage were allowed, we'd have two calls to foo<Z> that would have to return different types . 但是,如果允许使用更早的用法,我们将有两个对foo<Z>调用,这些调用必须返回不同的type This could only fly if the actual value f were the template parameter. 仅当实际值f为模板参数时,才可以执行此操作。


Note that clang compiling the declaration is not, in of itself, a compiler error. 注意,clang编译声明本身并不是编译器错误。 This is a class of situations that are ill-formed, no diagnostic required. 这是一类状况不佳的情况,不需要诊断。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 有没有办法将`constexpr`值传递给lambda,以便在lambda中保持`constexpr`? - Is there a way to pass a `constexpr` value into lambda so that it remains `constexpr` inside that lambda? 如何指定返回类的 constexpr 函数的类型(不使用 auto 关键字) - How to specify type of a constexpr function returning a class (without resorting to auto keyword) 我可以将 lambda 传递给 constexpr 构造函数吗? - Can I pass a lambda to a constexpr constructor? 不能使用显式类型的lambda - Cannot use explicitly typed lambda 无法获得返回constexpr auto的函数类型 - Unable to get type of function returning constexpr auto 为什么要明确指定模板参数的类型? - Why explicitly specify the type of a template argument? 显式指定泛型 lambda 的 operator() 模板参数是否合法? - Is it legal to explicitly specify a generic lambda's operator() template arguments? 是否可以在传递给 function 的通用 lambda 中明确指定模板 arguments? - Is it possible to explicitly specify template arguments in a generic lambda passed to a function? lambda表达式中ref-captured和非显式捕获的constexpr变量之间的区别 - Difference between ref-captured and non-explicitly captured constexpr variables in lambda-expressions 我可以使用C ++ 17 captureless lambda constexpr转换运算符的结果作为函数指针模板非类型参数吗? - Can I use the result of a C++17 captureless lambda constexpr conversion operator as a function pointer template non-type argument?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM