15

使用はオーバーロードの高く評価されている方法の 1 つであることは理解していますtemplatesが、なぜauto関数パラメーターの型推定に使用できないので、関数のオーバーロードを支援するのか疑問に思っていました。

N36907.6.1.4/3 で、auto を使用してラムダ式を汎用にすることができると述べており、この例を提供しています

auto glambda = [](int i, auto a) { return i; };//OK: a generic lambda

(注: これは N3485 には記載されていません)

1).なぜ私は通常の関数に対して同様のことを行うことができないのですか?

void swap(auto& param1, decltype(param1)& param2)
{
     decltype(param1) temp = param1;
     param1 = param2;
     param2 = temp;
}

これによりエラーが発生しerror : parameters declared autoます。

N3690 7.1.6.4/4 から

auto または decltype(auto) を使用して宣言された変数の型は、その初期化子から推測されます。この使用は、ブロック (6.3)、名前空間スコープ (3.3.6)、および for-init-statement (6.5.3) で変数を宣言するときに許可されます。[...]

param1andparam2がブロック スコープに該当し、自動控除の対象になると仮定するのは間違っていますか?

2)。そのような機能が許可されている場合、落とし穴は何でしょうか?

私はgcc 4.8.1を使用しています。

ありがとうございました

4

4 に答える 4

2

N3690 は C++14 の委員会草案です。つまり、まだリリースされておらず、ほとんどのコンパイラでまだ実装されていない次の C++ 標準です。したがって、ジェネリックラムダが実装されている場合は、コンパイラのドキュメントを参照する必要があります-実装されていないと思います。

ただし、gcc を使用すると、新しい標準が正式にリリースされる前に C++14 機能が実装される可能性が高くなりますが、コマンド ライン フラグを使用して C++14 サポートを明示的に有効にする必要がある場合があります。ドキュメントを見ると、-std=gnu++1y

このサイトによると、一般的なラムダはまだ GCC に実装されていません。

更新:パラメータ を使用する通常のジェネリック関数autoについて: これらは存在せず、次回は登場しません。その理由は、型を参照してテンプレート メタ関数を型に直接適用できるため、テンプレート化された関数の型が少しだけ冗長になり、より強力になるためです。ジェネリック ラムダでは、これは を使用することによってのみ実行できます。これはdecltype(a)少し面倒であり、注意して使用する必要があります。これは、テンプレートの引数推定とは動作が少し異なるためです。
auto パラメータと比較したテンプレートの追加のボーナスは、型安全性または表現力がもう少し高いことです。

void func(auto a, auto b);  //a and b might be different types

template <class T>
void func(T a, T b); //a and b must be the same type
于 2013-06-21T09:42:45.180 に答える
1

ForEveRの答えに加えて:

たとえば、通常の関数に対して同様のことを行うことができないのはなぜですか

void swap(auto& param1, decltype(param1)& param2)

単に言語がこれを許可していないためです。以前autoは、C++ 11 で (再) 発明されたもので、テンプレートを使用して実現できました。

template <class T, class U>
void swap(T& param1, U& param2);

C++11 もラムダ式を導入し、C++14 では基本的にoperator ()テンプレートであるラムダであるポリモーフィック ラムダが導入される可能性があります。たとえば、テンプレートの構文と同様の構文が、多相ラムダについて考慮されました (例はN3418から取得) 。

[]<class T>(T* p) { /* ... */ }

最後に、推奨される構文はauto、テンプレート パラメーター リストを導入するのではなく、使用することでした。

OPが示唆するように、この簡潔な構文を関数テンプレートに拡張することを検討できるのは事実ですが、私の知る限り、委員会はこの可能性を検討していません。将来的にはそうなるかもしれませんが、誰かが正式に提案しなければなりません。これは「あると便利な機能」かもしれませんが、私見では、これは言語にあまり影響を与えない単なる構文糖衣です。

また、この簡潔な構文 (テンプレート パラメーター リストなし) をテンプレート クラスに使用する方法がわかりません。おそらく、テンプレート関数の構文をテンプレート クラスの構文から分岐させることは価値がありません。

于 2013-06-21T09:56:05.367 に答える
0

あなたが望むものを書く方法はすでにあります:-

template <class T>
void swap(T& param1, T& param2)
{
     T temp = param1;
     param1 = param2;
     param2 = temp;
}

では、以前はできなかったことができないような新しい構文を作成する必要はありません。ラムダへの提案された変更は、以前はできなかった一般的なラムダを許可することです。テンプレート構文を使用する構文は、ここでは醜いものになると思います。

于 2013-06-21T09:56:26.173 に答える