C2664 не может преобразовать в && значение - PullRequest
1 голос
/ 14 июля 2020

Компилятор хочет, чтобы мое lvalue было ссылкой на rvalue, и я не понимаю, почему.

Мои вопросы:

  1. Почему "dataLen" const, даже если он был объявлен non const, и лямбда-функция по умолчанию должна перехватывать ссылку?
  2. Почему компилятор пытается преобразовать в ссылку rvalue "unsigned __int64 &&", даже если она была объявлена ​​"unsigned long long" (нет ссылки на rvalue ) для tupleByteVector_content?

Я думаю, это из-за лямбда-захвата, но, пожалуйста, посмотрите этот упрощенный рабочий процесс ниже:

void read_socket()
{
  std::vector<std::tuple<unsigned long long, std::vector<unsigned char>>> tupleByteVector_content;
  read_socket_readSome(tupleByteVector_content, [this, &tupleByteVector_content]() {
    //use tuple vector
  });
}

//catch the tuple vector by reference
void read_socket_readSome(std::vector<std::tuple<unsigned long long, const std::shared_ptr<Session>& session, std::vector<unsigned char>>> & tupleByteVector_content, std::function<void()> && continueReadFunction)
{
  //Read data length from a asio socket
  std::shared_ptr<asio::streambuf> len_buffer = std::make_shared<asio::streambuf>();
  asio::async_read(session->connection->socket->next_layer(), *len_buffer, asio::transfer_exactly(1), [&, 
  this, session, len_buffer, tupleByteVector_content, continueReadFunction](const error_code& ec, std::size_t bytes_transferred) {

    //the first value I want to save
    unsigned long long dataLen = BytesToLength(len_buffer);

    //Read data from a asio socket
    std::shared_ptr<asio::streambuf> data_buffer = std::make_shared<asio::streambuf>();
    asio::async_read(session->connection->socket->next_layer(), *data_buffer, asio::transfer_exactly(dataLen), [&, this, dataLen, data_buffer, tupleByteVector_content, session, continueReadFunction](const error_code& ec, std::size_t bytes_transferred) {

        //ERROR HERE: ----------->

        std::tuple<unsigned long long, std::vector<unsigned char>> t = 
          std::make_tuple<unsigned long long, std::vector<unsigned char>>(

          dataLen, // ERROR C2664, cant convert argument 1 from "const unsigned __int64" to "unsigned __int64 &&"

          { asio::buffers_begin(data_buffer->data()), asio::buffers_end(data_buffer->data()) });

        //ERROR HERE: <-----------
        
        tupleByteVector_content.push_back(t);

        continueReadFunction();

    });
  });
}

EDIT: мне удалось скомпилировать этот кортеж:

std::tuple<unsigned long long, std::vector<unsigned char>> t = { dataLen, { asio::buffers_begin(data_buffer->data()), asio::buffers_end(data_buffer->data()) } };

Но тогда push_back в вектор выдает ошибку: error C2663: [...] :: push_back ": для 2 перегрузок нет преобразования для this-pointer (свободный перевод на английский sh от себя)

1 Ответ

3 голосов
/ 14 июля 2020
  1. dataLen обрабатывается как const , потому что вы захватываете его по значению:

    [&, this, dataLen,
              ^^^
    

По умолчанию генерируется оператор вызова функции для закрытия помечено как const , поэтому внутри метода const вы можете только читать данные. Изменения не допускаются, если вы не добавите mutable в определение лямбды.

Когда вы используете make_tuple, вы должны полагаться на вывод аргументов шаблона вместо того, чтобы указывать типы явно, как вы это делали. Краткая версия вашей проблемы:

 int i;
 std::tuple<int> t = std::make_tuple<int>(i);

i - это именованный объект, поэтому это lvalue . Набрав make_tuple<int>, вы делаете подпись make_tuple как: make_tuple(int&&). Это место, где компилятор жалуется, потому что i as lvalue не может быть привязан к ссылке rvalue . При выводе аргумента параметр make_tuple определяется как: int&, и в этом случае i может быть привязано.

push_back на vector не работает, потому что снова вы захваченный вектор по значению. push_back изменяет объект, что недопустимо при вызове объекта const . Вы должны записать его по ссылке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...