Есть ли способ хранить std :: atomi c, внутри структуры, внутри std :: pair? - PullRequest
0 голосов
/ 15 апреля 2020

VS2017 выдает следующую ошибку, когда я пытаюсь добавить std::atomic к структуре, хранящейся в std::pair (внутри std::unordered_map):

error C2660: 'std::pair<uint32_t,AtomicStruct>::pair': function does not take 2 arguments

Я упростил проблему в следующий код (для ясности / фокуса удаляем std :: unordered_map):

#include <iostream> // std::cout
#include <utility>  // std::pair
#include <atomic>   // std::atomic

struct AtomicStruct
{
    std::atomic_uint32_t a;

    // associated data goes here...
};

using AtomicPair = std::pair<uint32_t, AtomicStruct>;

int main()
{
    AtomicStruct as = { 1 };                    // This initializer works just fine
    std::cout << "as: " << as.a << std::endl;   // Outputs "as: 1" as expected

    AtomicPair pr1(0, as);                      // error C2660
    AtomicPair pr2(0, { 1 });                   // error C2660

    return 0;
}

Из того, что я до сих пор собирал вместе:

  • std::atomic удаляет copy-constructor. Шаблон
  • std::pair проверяет наличие параметров is_copy_constructible, когда параметры указывают first и second в std :: pair.
  • Поскольку параметр std::atomic, или второй, не является is_copy_constructible, определение конструктора не создается.
  • Затем компилятор возвращается к конструктору копирования std::pair(const std::pair&) = default, который завершается ошибкой, поскольку число неверные параметры (два вместо одного), а также неверный тип.

Если я удаляю std::atomic из структуры, я могу поместить его непосредственно в std::pair

std::pair<uint32_t, std::atomic_uint32_t> pr3(0, 1);    // Works!

Я подумал, что, возможно, инициализатор слишком рано использовался для строительства, а также попытался:

AtomicPair pr4(0, { { 1 } });  // error C2660

Может быть, я упускаю что-то очевидное ... Кто-нибудь знает способ хранения структур, содержащих std::atomic s в std::pair?

1 Ответ

0 голосов
/ 15 апреля 2020

Поскольку ответ по ссылке был дан в комментариях, и я не знаю, как долго это будет продолжаться, я копирую / вставляю важные биты ответа / примера, предоставленного @NathanOliver, на случай, если кто-то еще нужен ответ.

Как указал @Nichol_Bolas, мое первоначальное намерение состояло в том, чтобы AtomicStruct была совокупностью; если кто-нибудь знает способ улучшить ответ ниже и сохранить AtomicStruct как совокупность, я открыт для предложений.

struct AtomicStruct
{
    std::atomic_uint32_t a;
    AtomicStruct(uint32_t a) : a(a) {}
    // associated data goes here...
};

int main()
{
    //... 
    AtomicPair pr1{std::piecewise_construct, std::forward_as_tuple(0), std::forward_as_tuple(1)};
    //...
}
...