2017-06-11 8 views
18

パンドラボックスを開くのが好きですが、それは私の気になることを止めるものではありません。簡単な例を考えてみましょう:テンプレートパラメータの中でconstexprラムダを宣言できますか?

#include <type_traits> 

template <auto> 
struct Foo: std::false_type { }; 

template <> 
struct Foo<[](){return 1;}()>:std::true_type { }; 

int main() { 
    static_assert(Foo<1>::value); 
} 

私はラムダが未評価のコンテキスト内で宣言することはできません知っているが、明らかにこれは、ここではそうではありません。もっと奇妙なクラン5.0.0(これは、最初は部分的にconstexprラムダをサポートしていると思います)does compile itです。

これはコンパイラのバグですか、これはC++ 17で許可されていますか?

答えて

24

いいえ、これはコンパイラのバグです。 gcc 7.1は正しくコードを拒否します。

[expr.prim.lambda]/2

ラムダ式は、その結果オブジェクト閉鎖オブジェクト呼ばれるprvalueあります。ラムダ式は評価されないオペランド、テンプレート引数の、エイリアス宣言、typedef宣言、または関数本体とデフォルト引数の外にある関数または関数テンプレートの宣言に現れてはならない。

太字で表示されている部分からわかるように、ラムダ式はテンプレート引数リストには表示されません。

これはまた、後続のノートで明らかにされている:

[注:意図は署名に表示されラムダを防止するためです。 - エンドノート]

私は推測していた場合、私はC++ 17で始まる、ラムダは暗黙のうちにconstexprあり、コンパイル時式で呼ばれることにそれらが有効になりた、のようなので、バグは約来ることを言うでしょうテンプレート引数。しかし、実際にはテンプレート引数でラムダを定義することは依然として不正です。


この制限はC++ 20で解消されています。 :)

+0

私は標準的な委員会の意図がそれを提示することだと思った、それは私が驚いたのは、コンパイルコードを驚いた理由です。私はちょっと待ってからあなたの答えを受け入れます。ありがとう! –

+0

*なぜ*これが違法になったのか?非常に便利で、メタプログラミングをもっと簡単にしているようです... –

+3

@DanielJourいいえ、ごめんなさい。しかしそれはメタプログラミングをもっと*混乱させるでしょう:) – Rakete1111

関連する問題