ошибка: невозможно получить адрес rvalue типа 'void'. Два класса с одинаковым рабочим процессом, но один выдает ошибку - PullRequest
0 голосов
/ 02 марта 2020

У меня есть две функции с похожим рабочим процессом. Один - измененный пример из NS3, а другой - изменение узла производителя.

Мой производитель

void
ProactiveProducer::SendData(Name dataName)
{
  // dataName.append(m_postfix);
  // dataName.appendVersion();
  if (!m_active)
    return;

  NS_LOG_FUNCTION_NOARGS();

  auto data = make_shared<Data>();
  data->setName(dataName);
  data->setFreshnessPeriod(::ndn::time::milliseconds(m_freshness.GetMilliSeconds()));

  data->setContent(make_shared< ::ndn::Buffer>(m_virtualPayloadSize));

  Signature signature;
  SignatureInfo signatureInfo(static_cast< ::ndn::tlv::SignatureTypeValue>(255));

  if (m_keyLocator.size() > 0) {
    signatureInfo.setKeyLocator(m_keyLocator);
  }

  signature.setInfo(signatureInfo);
  signature.setValue(::ndn::makeNonNegativeIntegerBlock(::ndn::tlv::SignatureValue, m_signature));

  data->setSignature(signature);

  NS_LOG_INFO("node(" << GetNode()->GetId() << ") responding with Data: " << data->getName());

  // to create real wire encoding
  data->wireEncode();

  m_transmittedDatas(data, this, m_face);
  m_appLink->onReceiveData(*data); 

  ScheduleNextPacket();
}

void
ProactiveProducer::ScheduleNextPacket()
{
  NS_LOG_DEBUG ("m_sendEvent: " << m_sendEvent.IsRunning());
  if (m_firstTime) {
    m_sendEvent = Simulator::Schedule(Seconds(0.0), &ProactiveProducer::SendData(m_prefix), this);
    m_firstTime = false;
  } else if (!m_sendEvent.IsRunning()) {
    m_sendEvent = Simulator::Schedule(Seconds(1.0 / m_frequency), &ProactiveProducer::SendData(m_prefix), this);
  }
}

Потребитель NS3

void
ModConsumer::SendPacket()
{
  // if the application isn't running don't do anything
  if (!m_active)
    return;

  NS_LOG_FUNCTION_NOARGS();

  // Will be an invalid packet
  uint32_t seq = std::numeric_limits<uint32_t>::max(); // invalid

  /*
    if the integer is positice the loop runs infinitely --> poor code
    - when the size of the list goes to 0 it will exit and therefore seq will be max int
    - the consumer seems to work based off of packets to be retransmitted.
    - removes the first entry in list of packets to be retransmitted
    - removes packet from list of retransmissions
    - then transmits that?
  */
  while (m_retxSeqs.size()) {
    seq = *m_retxSeqs.begin();
    m_retxSeqs.erase(m_retxSeqs.begin());
    break;
  }

  // will check fail conditions or increment sequence
  if (seq == std::numeric_limits<uint32_t>::max()) {
    // NS_LOG_DEBUG ("Reached max Sequence: " << seq << " max_seq: " << m_seq);
    if (m_seqMax != std::numeric_limits<uint32_t>::max()) {
      if (m_seq >= m_seqMax) {
        NS_LOG_DEBUG ("maximum sequence number has been requested, m_seq: " << m_seq << " m_seqMax: " << m_seqMax);
        return; // we are totally done
      }
    }

    seq = m_seq++;
  }

  shared_ptr<Name> nameWithSequence = make_shared<Name>(m_interestName);
  nameWithSequence->appendSequenceNumber(seq);

  shared_ptr<Interest> interest = make_shared<Interest>();
  interest->setNonce(m_rand->GetValue(0, std::numeric_limits<uint32_t>::max()));
  interest->setName(*nameWithSequence);
  interest->setCanBePrefix(false);
  time::milliseconds interestLifeTime(m_interestLifeTime.GetMilliSeconds());
  interest->setInterestLifetime(interestLifeTime);
  interest->setMustBeFresh(true);

  // NS_LOG_DEBUG ("Requesting Interest: \n" << *interest);
  // NS_LOG_INFO("> Interest for " << seq);

  WillSendOutInterest(seq);

  m_transmittedInterests(interest, this, m_face);
  m_appLink->onReceiveInterest(*interest);

  ScheduleNextPacket();
}

// Yes this is a different class, pasting for convenience
void
ModConsumerCbr::ScheduleNextPacket()
{
  NS_LOG_DEBUG ("m_sendEvent: " << m_sendEvent.IsRunning());
  if (m_firstTime) {
    m_sendEvent = Simulator::Schedule(Seconds(0.0), &ModConsumer::SendPacket, this);
    m_firstTime = false;
  } else if (!m_sendEvent.IsRunning()) {
    m_sendEvent = Simulator::Schedule(Seconds(1.0 / m_frequency), &ModConsumer::SendPacket, this);
  }
}

Когда я запускаю код, компилятор выдает следующую ошибку для класса производителя

error: cannot take the address of an rvalue of type 'void'
    m_sendEvent = Simulator::Schedule(Seconds(0.0), &ProactiveProducer::SendData(m_prefix), this);

Мне кажется, я понимаю, почему будет выдана ошибка. Я передаю функцию типа void. Это не должно быть адресуемым. Поэтому я не могу понять, как потребитель правильно компилирует и работает. Любые предложения относительно того, что я пропускаю, будут с благодарностью. Я новичок в C ++.

Ответы [ 2 ]

3 голосов
/ 02 марта 2020

Сообщение об ошибке

ошибка: невозможно получить адрес значения типа 'void'

достаточно ясно

В этом утверждении

m_sendEvent = Simulator::Schedule(Seconds(0.0), &ProactiveProducer::SendData(m_prefix), this);

вторым аргументом является выражение вызова функции, имеющее тип void - тип возврата функции SendData. Поэтому совершенно неясно, чего вы пытаетесь достичь, взяв адрес ab неполного объекта типа void, который, кроме того, является значением.

В противоположность вашему коду в этом выражении

m_sendEvent = Simulator::Schedule(Seconds(0.0), &ModConsumer::SendPacket, this);

берется адрес функции-члена. Так что эти вызовы семантически разные.

1 голос
/ 02 марта 2020

Изменить эту строку

m_sendEvent = Simulator::Schedule(Seconds(0.0), &ProactiveProducer::SendData(m_prefix), this);

на эту

m_sendEvent = Simulator::Schedule(Seconds(0.0), &ProactiveProducer::SendData, this, m_prefix);

Ссылка: https://www.nsnam.org/doxygen/classns3_1_1_simulator.html#aec5dd434c42edd6c38ef249d2960c321

...