関数パラメーターのテンプレート引数プレースホルダーとしての「auto」


22

C ++ 20ではauto、関数パラメーター型を使用できます。

関数パラメーター型のautoテンプレート引数プレースホルダーとして使用することもできますか(似ていないが、C ++ 17 template <auto>の精神で)。

したがって、C ++ 20より前の次のコード:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second;
}

次のように書くことができます:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second;
}

それはコンパイルし、概念の実験的なGCC実装でうまく動作します

C ++ 20での正当な構文ですか?


私が聞いたことから、制約なしはauto 直接 templatized typename XYZに変換されます。これは、それが正当な構文であることを強く示唆しています。きちんと
フルーイッシュ

2
なお、クランとが不一致とクランとGCCかどうかについて同じ不一致を有することautoで許可されている[](const std::pair<auto, auto>& p){}(持つかどうか-std=c++2a、または-std=c++17)。
ウォールナット


ありがとう@DavisHerring-私は文言を修正しました
アミール・カーシュ

回答:


17

この構文はC ++ Concepts Technical Specificationで有効ですが、C ++ 20では無効です。C ++ 20の概念でautoは、関数パラメーター型の最上位でのみ許可されます。関連するルールは、[dcl.spec.auto]パラグラフ2です。

プレースホルダ型指定子フォームの型制約 [optが】autoとして使用することができる赤緯指定子赤緯指定子-配列パラメータ宣言、関数宣言またはラムダ式がない場合、及びトレーリングリターンタイプを導入するauto タイプ指定子(以下を参照)は、関数宣言またはラムダ式の汎用パラメータータイププレースホルダーです。。[注:ジェネリックパラメータータイプのプレースホルダーがあることは、関数が省略された関数テンプレート(9.3.3.5 [dcl.fct])またはラムダがジェネリックラムダ(7.5.5 [expr.prim.lambda])であることを示します。—エンドノート]

(執筆時点で最新のワーキングドラフトの文言を確認すると、多少異なるルールが見つかります。上記のルールは、プラハでのC ++ 20最終ドラフトに投票されたコアの問題2447によって変更されました。 1週間前の委員会。)

供述指定子関数パラメータでsがパラメータ宣言の開始時にキーワードやタイプ名の最初のシーケンスです。上記のルールはauto、トップレベルで許可します:

void f(auto x);

...しかし、decl-specifierとしてのみ。decl-specifierauto内にネストされている場合は許可されません。

void f(std::vector<auto> x);

...また、パラメータタイプの他の場所では許可されていません。

void f(void (*p)(auto));

うわぁ、知らなかった!現在、CWGリンクは404を提供していますが、この制限の根拠を簡単に説明できますか?
LF

これはまったくがっかりです。
フューリーシュ

1
申し訳ありませんが、CWGの問題とその文言の変更はまだ公開されていません。問題のルールは、open-std.org / jtc1 / sc22 / wg21 / docs / papers / 2018 / p1141r2.htmlによって導入されたものであり、その意図/根拠は、一般的なラムダに対してすでに許可されているものと一致するものでした。
リチャードスミス

4
@LF:CWGの問題はとにかく関係ありません:auto末尾の戻り値の型の特定の使用がこの種のauto使用としてカウントされることを意味する文言エラーを修正しました。
デイビスニシン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.