[解決済み] パラメータパックの二重省略演算子「... ...」とは何ですか?
質問
gcc の新しい C++11 ヘッダーの現在の実装を見ているときに、"......" トークンに遭遇しました。次のコードで確認することができます。 は正常にコンパイルされます。 [via godbolt.org]。
template <typename T>
struct X
{ /* ... */ };
template <typename T, typename ... U>
struct X<T(U......)> // this line is the important one
{ /* ... */ };
さて、このトークンの意味は何でしょうか?
edit: 質問タイトルの "......" を SO が "......" に切り捨てたようです、本当は "......" の意味でした。)
どのように解決するのですか?
その変な例はすべて、通常のシングルエリプスの場合と対になっています。
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes...)>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes......)>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
{ typedef _Res result_type; };
私の推測では、ダブルエリプシスと同じような意味合いで
_ArgTypes..., ...
つまり、C言語スタイルのvarargsリストに続くバリアドテンプレート展開です。
以下はテストです。 をテストしてみました。
編集してください。 これは適合しているように見えます。§8.3.5/3では、パラメータリストを形成する一つの方法として
パラメータ宣言リスト opt ... <サブ opt
つまり、ダブルエリプシスとは、パラメータパックで終わるparameter-declaration-listと、それに続くもう一つのエリプシスによって形成されるものです。
カンマは純粋にオプションです。8.3.5/4では、次のように書かれています。
構文的に正しく、"... "が抽象宣言文の一部でない場合、", ... "は"... "と同義である。
これは は の中で、抽象宣言子(abstract-declarator)です。 [編集] です。 が、Johannesは、彼らがパラメータ宣言の中の抽象的な宣言子を参照していることをうまく指摘しています。なぜquot;part of a parameter-declarationと言わなかったのか、なぜこの文章は単なる情報提供のメモではないのか...と思っています。
さらに
va_begin()
で
<cstdarg>
はバラグリストの前にパラメータが必要なので、プロトタイプの
f(...)
は C++ で特に許可されているものですが、これは役に立ちません。C99とのクロスリファレンスでは、プレーンなCでは違法です。
使用上の注意
リクエストにより はデモです。 のダブルエリプシスです。
#include <cstdio>
#include <string>
template< typename T >
T const &printf_helper( T const &x )
{ return x; }
char const *printf_helper( std::string const &x )
{ return x.c_str(); }
template< typename ... Req, typename ... Given >
int wrap_printf( int (*fn)( Req... ... ), Given ... args ) {
return fn( printf_helper( args ) ... );
}
int main() {
wrap_printf( &std::printf, "Hello %s\n", std::string( "world!" ) );
wrap_printf( &std::fprintf, stderr, std::string( "Error %d" ), 5 );
}
関連
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み] floatとdoubleの違いは何ですか?
-
[解決済み] ダブルコロン「:」の意味を教えてください。
-
[解決済み】C/C++の"-->"演算子とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】'cout'は型名ではない
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない