[解決済み] C++11で削除された関数がオーバーロードの解決に参加するのはなぜですか?
質問
なぜ C++11 では
" を使用しています。
delete
d" 関数が過負荷の解決に参加するようになりました。
?
なぜこれが有用なのでしょうか?あるいは言い換えれば、なぜ完全に削除されるのではなく、隠されるのでしょうか?
どのように解決するのですか?
の目的の半分は
= delete
構文の目的の半分は、特定のパラメータで特定の関数を呼び出さないようにすることです。これは主に、ある特定のシナリオで暗黙のうちに変換されるのを防ぐためです。特定のオーバーロードを禁止するためには、オーバーロードの解決に参加する必要があります。
引用した回答は、完璧な例を示しています。
struct onlydouble {
onlydouble(std::intmax_t) = delete;
onlydouble(double);
};
もし
delete
が関数を完全に削除した場合、その分
= delete
の構文はこれと同等になります。
struct onlydouble2 {
onlydouble2(double);
};
こんなこともできるんですね。
onlydouble2 val(20);
これは合法的なC++です。コンパイラはすべてのコンストラクタを調べますが、どれも直接整数型を取りません。しかし、そのうちのひとつは暗黙の変換の後にそれを取ることができます。だから、それを呼び出すのです。
onlydouble val(20);
これは
ではない
合法的な C++ ではありません。コンパイラはすべてのコンストラクタを調べ、その中には
delete
d のものも含めてすべてのコンストラクタを調べます。これは、完全に一致する
std::intmax_t
(これはどんな整数リテラルにも正確にマッチします)。そのため、コンパイラはそれを選択し、すぐにエラーを出します。
delete
d 関数を選択したためです。
= delete
は、単に「これは存在しない」という意味ではなく、「私はこれを禁止する」という意味で、より強い表現です。
私は、C++ 標準がなぜ = delete は "this does not exist" の代わりに "I forbid this" を意味すると言っているのかを尋ねていました。
それは、"this does not exist.と言うのに特別な文法を必要としないからです。 はできません。 を表すものです。ですから、私たちは、"I forbid this"と言うために特別な文法を取得し、他のものは取得しないのです。
明示的に"this does not exist"の文法を持つことで得られる唯一の機能は、誰かが後でそれを存在すると宣言することを防ぐことでしょう。そしてそれは、それ自身の文法を必要とするほど有用ではありません。
コピーコンストラクタが存在しないことを宣言する方法はありませんし、その存在は無意味な曖昧さを引き起こす可能性があります。
コピーコンストラクタは特殊なメンバ関数です。すべてのクラス は常に はコピー コンストラクタを持っています。ちょうど、コピー代入演算子、移動コンストラクタなどが常にあるようにです。
これらの関数は存在します。問題は、それらを呼び出すことが合法であるかどうかだけです。もし、あなたが
= delete
が存在しないことを意味すると言おうものなら、仕様書は関数が存在しないことが何を意味するのかを説明しなければならないでしょう。これは、仕様が扱う概念ではありません。
まだ宣言/定義されていない関数を呼び出そうとすると、コンパイラはエラーになります。しかし、エラーになるのは 未定義識別子 のためであり、quot;function doesn't exist"エラーのためではありません(たとえコンパイラがそのように報告したとしても)。さまざまなコンストラクタはすべてオーバーロード解決によって呼び出されるため、それらの "存在" はその点では処理されます。
すべての場合において、識別子を介して宣言された関数、またはコンストラクタ/デストラクタ (これも識別子を介して宣言され、単なる型識別子) が存在します。演算子のオーバーローディングは、構文上の糖分の後ろに識別子を隠しますが、それはまだそこにあります。
C++ 仕様は、存在しない関数という概念を扱うことができません。オーバーロードの不一致は扱えます。しかし、存在しないものについてはわかりません。そこで
= delete
は、あまり役に立たない "pretend I never wrote this line." よりも、はるかに役に立つ "attempts to call this fail" の観点から定義されています。
そしてもう一度、最初の部分を読み直してみてください。あなたは
はできません。
を "function doesn't exist." とすることはできません。それがそのように定義されているもう一つの理由です。
= delete
構文の主な用途のひとつは、特定のパラメータタイプを使用するようユーザに強制したり、明示的にキャストしたりすることです。基本的には、暗黙の型変換を回避するためです。
あなたの提案はそれをしないでしょう。
関連
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】Enterキーを押して続行する
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】C++の余分な資格エラー
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較