Как мне выполнить std :: move xvalue в void * ptr? - PullRequest
0 голосов
/ 03 октября 2019

Я написал оболочку для типа данных очереди FreeRTOS. Который является типом данных C. Теперь для примитивов и «простых» типов данных реализация работает отлично. Однако я не могу найти общий способ передачи владения в очередь FreeRTOS, используя, например, std :: unique_ptr.

Да, использование ptr.release () решит проблему, но это приведет кКласс RTOSQueue намного менее универсален. Что если я передаю структуру, в которой переменная-член имеет std :: unique_ptr? Я не должен писать специализацию для каждой возможной структуры.

#include <FreeRTOS.h>
#include <queue.h>

template <class T>
class RTOSQueue {
    QueueHandle_t queueHandle;
    TickType_t timeout;

public:
    RTOSQueue(size_t len, TickType_t timeout) : timeout(timeout) {
        queueHandle = xQueueCreate(len, sizeof(T));
    }

    void enqueue(const T& v) {
        xQueueSendToBack(queueHandle, static_cast<const void*>(&std::move(v)), timeout);
    }

    T dequeue() {
        uint8_t rxBuffer[sizeof(T)];
        T rxValue;

        xQueueReceive(queueHandle, rxBuffer, timeout);
        std::memcpy(&rxValue, rxBuffer, sizeof(T));

        return std::move(rxValue);
    }
};

struct S {
  std::unique_ptr ptr = std::make_unique(1234);
}

int main() {
  RTOSQueue q;
  S s;

  q.enqueue(s);
}

Текущая реализация дает

../include/RTOSCircularBuffer.hpp:18:64: error: taking address of xvalue (rvalue reference)
         xQueueSendToBack(queueHandle, static_cast<const void*>(&std::move(v)), timeout);

, которая показывает, что текущий код является недействительным C ++. Важной целью является предотвращение разрушения внутренней очереди v, но я не могу найти аккуратный способ, то есть без ненужного копирования, выполнить это.

...