次のコードの foo()
関数についてお聞きしたいです。
cpp
1void foo(int cb()) { 2 cout << cb() << endl; 3} 4 5int bar() { return 0; } 6 7int main(void) { 8 foo(bar); 9 10 // ↓コンパイルエラー 11 // void funcptr(int()) = foo; 12}
個人的には void foo(int cb());
という関数の引数 cb は「int 型を返す引数なしの関数」型、になるべきなのではないかと思います。しかし、実際にはこれは関数 ポインタ 型としてパースされるようです。決して int
型の引数が int *
に変換されたりはしないのに、なぜこのような挙動になのでしょうか?
無論、関数そのものを受け渡しする、ということがナンセンスというか不可能であって、関数を引数にするならポインタにならざるを得ないことは分かっています。しかし、きちんと関数ポインタであることを明記した表記void foo(int (*cb)());
が存在するので、このような表記法は不要なのではないかと思うのですが...
なお、main() 関数内でコメントアウトしたように、変数宣言として使おうとすると (当然関数の前方宣言と解釈され) 想像通りのエラーとなりました。
このようなことを考えたのはクラスの初期化構文の曖昧さについて調べていたからです。コンストラクタ呼び出しのつもりが、関数の前方宣言になってしまうという曖昧さです: Most vexing parse - Wikipedia
引数が関数ポインタとして扱われさえしなければ、そして関数型の引数を禁止すれば、上の Wikipedia のページのコードは問題なくパースできるのではないかと不思議に思っています。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/01/30 06:17