あいまいな関数のオーバーロード [例 max()]

ブランドン

類似しているが異なるテンプレート シグネチャを持つ C++ の関数をオーバーロードすることは可能ですか。

max() 関数について考えてみましょう。max()次の 3 つのオプションのペアを受け取ることができる関数が必要な場合: int*int範囲、int反復子の範囲。

STL には、この機能が 2 つの機能に分割されています。

では、C++ でこの動作を実現できますか、または実現できませんか? もしそうなら、どのようにしますか?

編集:これは正常に作成max(vec.begin(), vec.end());およびmax(vec[0], vec[1]);コンパイルされ、2 つの渡されたオブジェクトの範囲の最大値と最大値を見つけます。個人的には、そうでなければ STL で 2 つの機能を組み合わせるのは不可能だと思いますが、実行できないことを確認します。

コリスト

現時点では、オーバーロードは制限されていないため、あいまいです。コンパイラーは、最初のものがイテレーターに使用されるべきではないことをどのように知っているのですか?

答えは簡単です、あなたはそれを伝えなければなりません。幸いなことに、標準では、std::iterator_traits渡されたイテレータ タイプに関するあらゆる種類の情報をクエリできるものが定義されています (イテレータである限り)。

ここでの最後の点が重要です:IFがstd::iterator_tags<T>入れ子になったのtypedefを持っていないiterator_category、そしてTイテレータではありません。したがって、メンバー検出を使用void_tして、指定された型がイテレーターであるかどうかを確認するカスタム特性を定義できます。

コードでは、次のようになります。

// C++17 void_t
template <typename...>
using void_t = void;

template <typename T, typename = void>
struct is_iterator : std::false_type {
};

template <typename T>
struct is_iterator<T, void_t<typename std::iterator_traits<T>::iterator_category>> : std::true_type {
};

template <typename T>
constexpr auto is_iterator_v = is_iterator<T>::value;

ここではis_iterator_v、便宜上constexpr 変数も定義しています

この特性を と組み合わせて使用​​しstd::enable_ifて、型Tがイテレータであるかどうかに基づいて、以前はあいまいであった 2 つのオーバーロードのいずれかを選択的に無効にすることができます。これまでに、単純にテンプレート宣言を置き換えるtemplate <typename T>ことにより、template <typename T, std::enable_if_t<is_iterator_v<T>, int> = 0>およびtemplate <typename T, std::enable_if<!is_iterator_v<T>, int> = 0>それぞれ。

すべてをまとめると、コードは次のようになります。

// C++17 void_t
template <typename...>
using void_t = void;

template <typename T, typename = void>
struct is_iterator : std::false_type {
};

template <typename T>
struct is_iterator<T, void_t<typename   std::iterator_traits<T>::iterator_category>> : std::true_type {
};

template <typename T>
constexpr auto is_iterator_v = is_iterator<T>::value;

template<typename T, std::enable_if_t<!is_iterator_v<T>, int> = 0>
constexpr T maximum(T a, T b)
{
    return (a > b) ? a : b;
}

template<typename Iter, std::enable_if_t<is_iterator_v<Iter>, int> = 0>
constexpr Iter maximum(Iter begin, Iter end)
{
    if(begin == end) {
        return end;
    }
    auto max = begin;
    for (; begin != end; ++begin) {
        if(*begin > *max) {
            max = begin;
        }
    }
    return max;
}

wandbox で実際の例を見つけることもできます

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

コンパイルしない関数をオーバーロードする簡単なSFINAEの例

分類Dev

max関数のキーのガイドラインは何ですか?そのキーはPythonの辞書キーに関連していますか?例:max(arg1、arg2、* args [、key])

分類Dev

.NETのベストプラクティスまたはフレームワークの例:関数のオーバーロードと新しい方法?

分類Dev

関数の特殊化/オーバーロードルールの例

分類Dev

enable_if:引数のないvoidメンバー関数の最小限の例

分類Dev

オーバーロード演算子についてのこの例を理解できません

分類Dev

関数テンプレートのオーバーロード:Stroustrupの例の理解

分類Dev

エラーが発生します:オーバーロードされた「max(Cents&、Cents&)」の呼び出しがあいまいです

分類Dev

$ "..."の例

分類Dev

Caffeフレームワーク:バッチサイズ、max_iter、test_iter、epochの実際の例

分類Dev

この例で関数をハードコーディングしない方法

分類Dev

BASH:関数がパイプされている場合にのみ、関数内でグローバル変数を更新できません(簡単な例)

分類Dev

JavaScriptの例でコールバック関数が機能しない

分類Dev

(私の例よりも)必要な作業が少ないオーバーロードされたメソッドのポインターを渡す一般的な方法はありますか?

分類Dev

Javaでオーバーロードとオーバーライドの両方のケースで共分散と反分散を示す関数の例を挙げてください。

分類Dev

Java:オーバーロードされたメソッド解決と可変引数-紛らわしい例

分類Dev

ツアーの例:なぜオーバーフローが発生しないのですか?

分類Dev

max-heightの別のdivを含むmax-heightのDiv(オーバーフローが機能しない)

分類Dev

Pythonの変更例外の印刷可能な出力(例:オーバーロード__builtins__)

分類Dev

Pythonの変更例外の印刷可能な出力(例:オーバーロード__builtins__)

分類Dev

コールバック関数の例

分類Dev

独自のデータを使用してmutate_at関数とmax()関数を使用してRでコードを試しました。警告メッセージが表示されます:maxへの欠落していない引数はありません

分類Dev

継承の紛らわしい例。コンストラクターはオーバーライドされますが、関数はオーバーライドされません。どうして?

分類Dev

jestグローバル変数の例

分類Dev

jestグローバル変数の例

分類Dev

jestグローバル変数の例

分類Dev

Typescript:関数のオーバーロードの型パラメーターをキーオフすることは可能ですか?(投稿例)

分類Dev

この例では、max()関数が2つのプロパティで異なる動作をするのはなぜですか?

分類Dev

サブクラスの迅速なプロトコル関数をオーバーライドする方法(例:UIViewのUILabel)

Related 関連記事

  1. 1

    コンパイルしない関数をオーバーロードする簡単なSFINAEの例

  2. 2

    max関数のキーのガイドラインは何ですか?そのキーはPythonの辞書キーに関連していますか?例:max(arg1、arg2、* args [、key])

  3. 3

    .NETのベストプラクティスまたはフレームワークの例:関数のオーバーロードと新しい方法?

  4. 4

    関数の特殊化/オーバーロードルールの例

  5. 5

    enable_if:引数のないvoidメンバー関数の最小限の例

  6. 6

    オーバーロード演算子についてのこの例を理解できません

  7. 7

    関数テンプレートのオーバーロード:Stroustrupの例の理解

  8. 8

    エラーが発生します:オーバーロードされた「max(Cents&、Cents&)」の呼び出しがあいまいです

  9. 9

    $ "..."の例

  10. 10

    Caffeフレームワーク:バッチサイズ、max_iter、test_iter、epochの実際の例

  11. 11

    この例で関数をハードコーディングしない方法

  12. 12

    BASH:関数がパイプされている場合にのみ、関数内でグローバル変数を更新できません(簡単な例)

  13. 13

    JavaScriptの例でコールバック関数が機能しない

  14. 14

    (私の例よりも)必要な作業が少ないオーバーロードされたメソッドのポインターを渡す一般的な方法はありますか?

  15. 15

    Javaでオーバーロードとオーバーライドの両方のケースで共分散と反分散を示す関数の例を挙げてください。

  16. 16

    Java:オーバーロードされたメソッド解決と可変引数-紛らわしい例

  17. 17

    ツアーの例:なぜオーバーフローが発生しないのですか?

  18. 18

    max-heightの別のdivを含むmax-heightのDiv(オーバーフローが機能しない)

  19. 19

    Pythonの変更例外の印刷可能な出力(例:オーバーロード__builtins__)

  20. 20

    Pythonの変更例外の印刷可能な出力(例:オーバーロード__builtins__)

  21. 21

    コールバック関数の例

  22. 22

    独自のデータを使用してmutate_at関数とmax()関数を使用してRでコードを試しました。警告メッセージが表示されます:maxへの欠落していない引数はありません

  23. 23

    継承の紛らわしい例。コンストラクターはオーバーライドされますが、関数はオーバーライドされません。どうして?

  24. 24

    jestグローバル変数の例

  25. 25

    jestグローバル変数の例

  26. 26

    jestグローバル変数の例

  27. 27

    Typescript:関数のオーバーロードの型パラメーターをキーオフすることは可能ですか?(投稿例)

  28. 28

    この例では、max()関数が2つのプロパティで異なる動作をするのはなぜですか?

  29. 29

    サブクラスの迅速なプロトコル関数をオーバーライドする方法(例:UIViewのUILabel)

ホットタグ

アーカイブ