簡體   English   中英

嘗試傳遞constexpr 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM