12

ISO/IEC 14882:2011(E) の 8.3.5.11 から:

関数型の typedef は、関数を宣言するために使用できますが、関数を定義するために使用してはなりません

標準は、次の例を示しています。

typedef void F();
F fv; // OK: equivalent to void fv();
F fv { } // ill-formed
void fv() { } // OK: definition of fv

このルールの動機は何ですか? 関数 typedef の潜在的な表現上の有用性を制限しているようです。

4

4 に答える 4

13

この質問はC++に関するものですが、C++はCtypedefから関数ポインタを継承しているため、Cでの同じ質問の説明をここで使用できます。Cの正式な説明があります。

国際標準の根拠 - プログラミング言語 C §6.9.1関数定義

引数リストは、宣言子に明示的に存在する必要があります。a から継承することはできませんtypedef(§6.7.5.3 を参照)。つまり、次の定義が与えられます。

typedef int p(int q, int r);

次のフラグメントは無効です:

p funk // weird
{ return q + r ; }

一部の現在の実装では、たとえば、charパラメーターの型を宣言されているかのように書き換えます。これは、引数がプロトタイプがない場合にintとして渡されることがわかっているためです。intただし、標準では、受け取った引数を、関数のエントリ時に代入によって変換するかのように変換する必要があります。したがって、型の書き換えは許可されなくなりました。

于 2013-07-25T05:05:09.543 に答える
7

それはおそらく歴史的な理由によるものです。typedefC への比較的遅い追加であり、既存の言語に追加されました (そして、コンパイラの解析フェーズでいくつかの問題を引き起こしました)。

また、関数定義では、パラメーターの名前を定義する必要があります (存在する場合)。関数には、関数の戻り値の型とパラメーターの型が含まれますが、パラメーター名は含まれません。たとえば、次のとおりです。

void (int)
void (int x)
void (int y)

は、同じ関数型を記述する 3 つの方法です。あなたが持っていた場合:

typedef void func_t(int);

次に、この仮想定義:

func_t some_func { }

intパラメータの名前を定義しません。それが合理的な方法でどのように解決されたのか、私にはわかりません。それは可能だと思いますが、それは決して行われませんでした。

しかし、肝心な点はおそらく、Dennis Ritchie がtypedef、関数定義で a を使用する方法を定義する努力をする価値があるとは考えていなかったか、単純にそれを考えていなかったということです。

于 2013-07-25T04:45:46.593 に答える
-4

ルールはあなたが引用したとおりです - typedef of function type shall not be used to define a function。例の 3 行目では、 function type で関数を定義しようとしていますF。これは標準では許可されていません。


編集
あなたが指摘したように、私はそれについてもっと説明しようとします。

3行目については、それが合法である場合、 F を typedef 定義: に置き換えることができます
void fv { }()。これは、C++ での正当な定義または宣言ではありません。

重要な点は、単純化のためにエイリアスを作成するだけであり、コンパイル時にtypedeftypedef の型を置き換えることができることだと思います。#define

于 2013-07-25T04:33:14.987 に答える