Граммер для создания безымянного экземпляра - PullRequest
1 голос
/ 28 мая 2020

Я делаю хеш-функцию для ключа pair < int,int >.

В любом случае, я нашел следующую реализацию, в которой используются std::hash<>:

typedef struct hasher_t {

        template <class T1, class T2>
        size_t operator()(const pair<T1,T2>& key) const {
            //standard hasher for T1, T2

            auto h1 = std::hash<T1>()(key.first);   //also possible
            auto h2 = std::hash<T2>()(key.second); //also possible

            /*
            auto h1 = std::hash<T1>{}(key.first);
            auto h2 = std::hash<T2>{}(key.second);
            */
            return h1 ^ (h2 - 1);
        }

    } hasher;

std::hash<T1>() и std::hash<T1>{} оба работают, но я не знаю, почему это работает.

Я даже не могу найти справочную статью по этому поводу.

Я предполагаю, что оба они создают буквально «безымянный временной экземпляр» для класса std::hash<T1> и вызовите метод operator()(T1). Это правильно?

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Да, оба создают временный std::hash, а затем вызывают operator() для временного объекта.

std::hash<T1>() выполняет инициализацию значения ,

1,5) при создании безымянного временного объекта с инициализатором, состоящим из пустой пары круглых скобок or braces (since C++11);

Временный объект инициализируется конструктором по умолчанию.

std::hash<T1>{} performes инициализация списка (начиная с C ++ 11),

2) инициализация безымянного временного объекта с помощью braced-init-list

В результате временный объект также инициализируется значением конструктором по умолчанию.

0 голосов
/ 28 мая 2020

std::hash<T> - это тип, а не функция. Вы можете рассматривать его как функтор . Итак, вам нужно создать его экземпляр.

Чтобы ответить на ваш вопрос, да, в обоих случаях создайте объект std::hash<T> и инициализируйте его, вызвав оператор ().

std::hash<T1>() выполняет инициализацию с использованием скобок. Это также известно как инициализация значения .

std::hash<T1>{} - это инициализация с использованием фигурных скобок. В auto h1 = std::hash<T1>{}(key.first); происходит следующее: {} создает экземпляр std::hash<T1>, а затем (key.first) вызывает оператора () на вашем экземпляре. Это также называется совокупная инициализация или инициализация списка .

В C ++ 11 и выше вы можете использовать std :: hash {} (ie, фигурные скобки вместо круглых) для построения объекта.

...