[解決済み] なぜ関数を別の関数の中で定義できないのですか?
質問
ラムダ関数を変数に代入できることは知っています。
コード内部で関数を宣言することはできても、定義することができないのはどういうことでしょうか?
例えば
#include <iostream>
int main()
{
// This is illegal
// int one(int bar) { return 13 + bar; }
// This is legal, but why would I want this?
int two(int bar);
// This gets the job done but man it's complicated
class three{
int m_iBar;
public:
three(int bar):m_iBar(13 + bar){}
operator int(){return m_iBar;}
};
std::cout << three(42) << '\n';
return 0;
}
そこで私が知りたいのは、なぜ C++ は
two
という無駄と思われるものを許し
three
という、はるかに複雑に見えるものがありますが、これは
one
?
EDITです。
回答から、コード内の宣言で名前空間汚染を防ぐことができそうです。しかし、私が聞きたかったのは、なぜ関数を宣言する機能は許可されているのに、関数を定義する機能は禁止されているのか、ということです。
どのように解決するのですか?
なぜ
one
が許されない理由は明らかではありません。ネストされた関数は、ずっと以前に
N0295
と言うものです。
C++にネストされた関数が導入されたことについて説明します。ネストされた 関数はよく理解されており、その導入にはコンパイラーベンダー、プログラマー、委員会のいずれもがほとんど コンパイラーベンダー、プログラマー、委員会のいずれからもほとんど努力は必要ありません。 ネストされた関数は重要な利点を提供します。
明らかにこの提案は却下されましたが、会議の議事録がオンラインで利用できないので
1993
の会議録がオンラインで利用できないため、この却下の根拠となる可能性のあるソースがありません。
実際この提案は C言語のラムダ式とクロージャ ++ を代替とすることができます。
ある記事[Bre88]とC++委員会への提案N0295[SH93]は、C++にネストした関数を追加することを提案しています。 委員会への提案 N0295 [SH93] は、C++にネストされた関数を追加することを提案しています。 ++ . ネストされた関数はラムダ式に似ているが、関数本体内のステートメントとして定義され、結果として生じるクロージャはその関数がアクティブでない限り使用できない。 クロージャは、その関数がアクティブでない限り、使用することができません。今回の提案 また、ラムダ式ごとに新しい型を追加するのではなく、通常の関数に近い形で実装し より通常の関数に近い形で実装する。 特別な関数ポインタでラムダ式を参照できるようにする。どちらの提案も これらの提案は、C++にテンプレートが追加される前に行われました。 ++ にテンプレートが追加される以前のものなので、ジェネリックアルゴリズムと組み合わせたネストされた関数の使用については言及していません。また、これらの提案には、ローカル変数をクロージャにコピーする方法が ありません。 また、これらの提案にはローカル変数をクロージャにコピーする方法がないため、生成されるネストされた関数はそのエンクロージャの外では全く使用できません。 を生成する入れ子関数は、その包含する関数の外側では完全に使用できません。
私たちが今ラムダを持っていることを考えると、ネストされた関数を見ることはないでしょう。なぜなら、この論文が概説するように、それらは同じ問題に対する代替案であり、ネストされた関数はラムダと比較していくつかの制限があるためです。
あなたの質問のこの部分に関して。
// This is legal, but why would I want this? int two(int bar);
欲しい関数を呼び出すのに便利な方法である場合があります。C++標準の草案では、セクション
3.4.1
[基本.lookup.unqual]。
は、1つの興味深い例を与えてくれます。
namespace NS {
class T { };
void f(T);
void g(T, int);
}
NS::T parm;
void g(NS::T, float);
int main() {
f(parm); // OK: calls NS::f
extern void g(NS::T, float);
g(parm, 1); // OK: calls g(NS::T, float)
}
関連
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] 0.1fを0にすると、なぜ10倍もパフォーマンスが落ちるのですか?
-
[解決済み] C++で仮想関数が必要な理由とは?
-
[解決済み] switch文の中で変数を宣言してはいけないのはなぜですか?
-
[解決済み] C++のヘッダーファイルで#ifndefと#defineが使われているのはなぜですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】識別子 "string "は未定義?
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】C++の余分な資格エラー
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] nからk個の要素の組み合わせをすべて返すアルゴリズム