2010-12-06 15 views
4

SOに参加した後、テンプレートを議論するトピックを開くたびにこの種の構文がよく見られます。私はGoogleで検索しようとしましたが、無駄でした。ここから複雑なC++テンプレートの構文

template<typename T> 
char (&f(T[1]))[1]; //what is it? what is the use of '[]' brackets and the integer in it? 

template<typename T> 
char (&f(...))[2]; //not this either 

int main() { char c[sizeof(f<void()>(0)) == 2]; } // and this? 

SFINAE with invalid function-type or array-type parameters?

私がコメントを入れている3行を説明してください。私は特に構文を理解したい。このような構文をテンプレートでのみ使用できますか?

答えて

4

次の二つの関数ポインタで

char (*XXX)(); 

今だけではなく、機能の一部の配列を作成する[N]()を交換する前に、あなたはそのパターンを見てきたかもしれない

// 1 
template<typename T> 
char (&f(...))[2]; 

// 2 
typedef char rettype[2]; 
template<typename T> 
rettype &f(...); 

同等であります*&に置き換えて、ポインタの代わりに参照を作成し、XXXを関数宣言子で置き換えます。次に、サイズがNの配列への参照を返す関数を取得します。


あなたは同様に型指定された関数の宣言が含まれているman signal、に見てみたいことがあります。あなたが実際に関数を宣言し、内部宣言子を取る場合は、同じパターン

void (* signal(int sig, void (*func)(int)))(int); 
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ take out that 

を得ることがintを取り、そのマニュアルページで説明したように、voidを返す関数へのポインタを返します。いくつかの条件が満たされない場合


次は、コンパイラエラーを生成するだけの方法です。 の場合、foo == 2falseとなり、作成された配列のサイズはゼロです。これはC++では不正であり、コンパイル時にエラーが発生します。 trueと評価された場合、配列が宣言されている以外は何も起こりません。

char c[some silly condition here]; 
+0

すてきな説明、ありがとう。その愚かな条件でサイズがゼロの配列が作成されたら、なぜその条件を入れましたか? –

+0

目的は、配列サイズの無効を使用して、特定のコードのコンパイルを防止することです(たとえば、特別に処理される特定の型のテンプレートのインスタンス化など)。 –

+0

@Pointer:「コンパイル時アサート」と呼ばれる概念です。 "通常の" assert()は、実行時にブール条件をチェックします。このメソッドを使用すると、コンパイル時にブール条件をチェックできます。たとえば、 'char c [CHAR_BIT == 8]'は、あなたのプログラムが 'CHAR_BIT == 9 ' – MSalters