無教養な文脈とは?
質問
"でつまずいたことがあります。 ここでは、なぜテンプレート引数deductionが機能しないのでしょうか? "最近、答えは "無教養な文脈です"に集約されるようになりました。
具体的には、最初のものはそのようなものだと言って、"詳細"のために標準にリダイレクトし、2番目のものは標準を引用しており、はっきり言って意味不明です。
誰か、私のような凡人に対して 非教養的なコンテキスト とは何か、それはいつ起こるのか、そしてなぜ起こるのか。
どのように解決するのですか?
控除
は、与えられた引数からテンプレートパラメータの型を決定するプロセスを指します。これは関数テンプレートに適用されます。
auto
そして、他のいくつかのケース(例えば、部分的な特殊化)にも適用されます。例えば、考えてみましょう。
template <typename T> void f(std::vector<T>);
ここで、もしあなたが
f(x)
と宣言した場合、ここで
std::vector<int> x;
と宣言した場合、次に
T
は
と推論される。
として
int
となり、特殊化された
f<int>
.
演繹が機能するためには、演繹されるテンプレートパラメータ型が演繹可能なコンテキストに出現していなければなりません。この例では、関数パラメータである
f
がそのような推論可能なコンテキストです。つまり、関数呼び出し式の引数によって、テンプレートパラメタ
T
は何であるべきかを決定することができます。
しかし、この他に
以外の
-のコンテキストもあり、そこでは演繹は不可能です。典型的な例として、" の左側に表示されるテンプレート パラメータがあります。
::
:
template <typename> struct Foo;
template <typename T> void g(typename Foo<T>::type);
この関数テンプレートでは
T
は非教育的な文脈にあります。したがって、次のように言うことはできません。
g(x)
と言って
T
. この理由は、任意の型と
メンバー
Foo<T>::type
. 例えば、specializationを持つことができます。
template <> struct Foo<int> { using type = double; };
template <> struct Foo<char> { using type = double; };
template <> struct Foo<float> { using type = bool; };
template <> struct Foo<long> { int type = 10; };
template <> struct Foo<unsigned> { };
もしあなたが
g(double{})
には二つの可能な答えがあります。
T
を呼び出すと
g(int{})
を呼び出しても答えはありません。一般に、クラス・テンプレートのパラメータとクラス・メンバの間には何の関係もありませんから、賢明な引数演繹は行えません。
時には、明示的に引数演繹を禁止することが有用な場合があります。これは例えば
std::forward
. からの変換がある場合です。
Foo<U>
から
Foo<T>
と言うように、その他の変換(例えば
std::string
と
char const *
). ここで、自由関数があるとします。
template <typename T> bool binary_function(Foo<T> lhs, Foo<T> rhs);
もしあなたが
binary_function(t, u)
を呼び出すと、推論が曖昧になり、その結果失敗する可能性があります。しかし、1つの引数だけを推論するのは合理的であり
ではなく
を推論することは合理的であり,暗黙の変換を許容する。ここで明示的に推論されないコンテキストが必要となり、例えばこのようになります。
template <typename T>
struct type_identity {
using type = T;
};
template <typename T>
bool binary_function(Foo<T> lhs, typename type_identity<Foo<T>>::type rhs)
{
return binary_function(lhs, rhs);
}
(のようなもので、このような控除問題を経験したことがあるかもしれません)。
std::min(1U, 2L)
.)
関連
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] ムーブセマンティクスとは何ですか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】なぜC++プログラマは'new'の使用を最小限に抑えなければならないのでしょうか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?