web-dev-qa-db-ja.com

std :: equal_toが動的割り当てを引き起こすのはなぜですか?

2つのstd::equal_toを比較するためにstd::pair<std::string, unsigned>を使用している次の簡単な例を考えてみます。 operator newはオーバーロードされているため、割り当てが行われたときにメッセージが出力されます(ライブコード here ):

#include <functional>
#include <string>
#include <iostream>

// overloaded to see when heap allocations take place
void* operator new(std::size_t n)
{
    std::cout << "Allocating " << n << std::endl;
    return malloc(n);
}

int main()
{
    using key_type = std::pair<std::string, unsigned>;
    auto key1 = std::make_pair(std::string("a_______long______string______"), 1);
    auto key2 = std::make_pair(std::string("a_______long______string______"), 1);

    std::cout << "Finished initial allocations\n\n" << std::endl;

    std::equal_to<key_type> eq;
    eq(key1, key2); // how can this cause dynamic allocation???
}

私が見ているメッセージは

Allocating 31
Allocating 31
Finished initial allocations


Allocating 31
Allocating 31

key1key2を比較すると、2つの割り当てが行われていることがわかります。しかし、なぜ? std::equal_toの演算子はconst参照によって引数を取得するため、割り当ては行われません...何が欠けていますか?ありがとう。

21
linuxfever

ペアのコピーを作成するためです。

keyXのタイプはstd::pair<std::string, int>です。 eqには、引数const std::pair<std::string, unsigned>&, const std::pair<std::string, unsigned>&の関数呼び出し演算子があります。型が一致しないため、参照を引数に直接バインドすることはできません。ただし、intは暗黙的にunsignedに変換できるため、指定されたペアは暗黙的に引数のペアに変換できます。

したがって、比較のために一時的な引数のペアを暗黙的に作成します。一時的な文字列を作成すると、メモリが割り当てられます。


std::equal_to<>を比較演算子として使用した場合、引数の型を推定するため、コピーは作成されず、変換は行われません。

29
eerorika