Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Multiple return types?

Multiple return types?

Scheduled Pinned Locked Moved General and Desktop
6 Posts 5 Posters 4.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    maybnxtseasn
    wrote on last edited by
    #1

    does anyone have any recommendations or advice on how i would do the following. Pretty much i want a function to possibly return 2 different types of structs depending on the XML it is parsing

    @
    struct Error
    {
    string errorMessage;
    string otherinfo;

    }

    struct Person
    {
    string firstname;
    string lastname;
    int age;
    float height;
    }

    Error/Person ParseXML(string XML)
    {
    if (<person>)
    return parsePerson(XML); // return a Error object
    else
    return parseError(XML); // return a person object

    }
    @

    [EDIT: code formatting, please wrap in @-tags, Volker]

    1 Reply Last reply
    0
    • M Offline
      M Offline
      maybnxtseasn
      wrote on last edited by
      #2

      Below is an example of my code if needed to show exactly what im trying
      @QList<CError> ParseError(QXmlStreamReader& streamReader)
      {
      QList<CError> errorList;
      CError errorBuffer;

      streamReader.readNext();
      while (!(streamReader.tokenType() == QXmlStreamReader::EndElement && streamReader.name() == "ErrorMessage")) {
      if (streamReader.tokenType() == QXmlStreamReader::StartElement) {
      if (streamReader.name() == "Title") {
      errorBuffer.strTitle = streamReader.readElementText();
      }
      if (streamReader.name() == "Message") {
      errorBuffer.strMessage = streamReader.readElementText();
      }
      }
      streamReader.readNext();
      }
      errorList.append(errorBuffer);
      return errorList;
      }

      QList<CSubscription> ParseSubscription(QXmlStreamReader& streamReader)
      {
      QList<CSubscription> subscriptionList;
      CSubscription subscriptionBuffer;

      streamReader.readNext();
      while (streamReader.tokenType() != QXmlStreamReader::EndDocument) {
      while (!(streamReader.tokenType() == QXmlStreamReader::EndElement && streamReader.name() == "Subscription")) {
      if (streamReader.tokenType() == QXmlStreamReader::StartElement) {
      if (streamReader.name() == "NewestVersion") {
      subscriptionBuffer.strNewestVersion = streamReader.readElementText();
      }
      if (streamReader.name() == "ProductName") {
      subscriptionBuffer.strGame = streamReader.readElementText();
      }
      if (streamReader.name() == "ExpiryDate") {
      subscriptionBuffer.strExpireDate = streamReader.readElementText();
      }
      if (streamReader.name() == "Detection") {
      subscriptionBuffer.strDetection = streamReader.readElementText();
      }
      }
      streamReader.readNext();
      }
      subscriptionList.append(subscriptionBuffer);
      }
      return subscriptionList;
      }

      QList<EITHERSTRUCT> ParseXML(QString& strXML)
      {
      QXmlStreamReader streamReader(strXML);

      while (!streamReader.atEnd()) {
      QXmlStreamReader::TokenType token = streamReader.readNext();
      if(token == QXmlStreamReader::StartDocument) {
      continue;
      }
      if(token == QXmlStreamReader::StartElement) {
      if (streamReader.name() == "ErrorMessage") {
      return ParseError(streamReader);
      }
      if (streamReader.name() == "Subscription") {
      return ParseSubscription(streamReader);
      }
      }
      }
      return SOME_ERROR;
      }@

      1 Reply Last reply
      0
      • L Offline
        L Offline
        lgeyer
        wrote on last edited by
        #3

        Well, you could return a QVariant, either containing an Error or Person struct, but for the sake of a good design I would not recommend doing so.

        A better option would be either adding isValid() to Person and/or adding hasError() / error() to the object enclosing ParseXML(). There are various other options, each better than an union return type.

        1 Reply Last reply
        0
        • JohanSoloJ Offline
          JohanSoloJ Offline
          JohanSolo
          wrote on last edited by
          #4

          I don't think you can return two different types of objects, in the sense that a function cannot be overloaded with another one which differs only by the return type. What you could do is to use polymorphism: if Person and Error inherit from the same base structure. Then your function should return a pointer on the base class, but on the other hand you should perform some casting to handle properly the returned element. You could of course return a status code (or error code) on top of your structure, which would help to handle the returned structure.

          `They did not know it was impossible, so they did it.'
          -- Mark Twain

          1 Reply Last reply
          0
          • G Offline
            G Offline
            goetz
            wrote on last edited by
            #5

            No, it is not possible. At compile time you need to decide which return type you need - you have to assign to the correct variable type.

            In use cases like yours, I usually create a return value object, consisting of a bool flag indicating an error or not, am error message and the expected return type. In case of an error, the error message is set, in case everything is ok the return type is filled in.

            @
            // Pseudo code

            class Person {
            string firstname;
            string lastname;
            int age;
            float height;
            };

            class PersonParseReturnVale {
            bool ok;
            string errormessage;
            Person *person;
            };

            PersonParseReturnVale ParseXML(string XML)
            {
            PersonParseReturnVale rv;
            if(parse_is_ok) {
            rv.ok = true;
            rv.person = new Person;
            rv.person.firstname = "bla";+
            } else {
            rv.ok = false;
            rv.errormessage = "Parse Errro";
            }
            return rv;
            }
            @

            http://www.catb.org/~esr/faqs/smart-questions.html

            1 Reply Last reply
            0
            • I Offline
              I Offline
              ivan
              wrote on last edited by
              #6

              You can always return a
              @ std::pair < Person, Error > @

              or a pair of pointers.
              An alternative, quite evil but fun way would be:
              @
              template < typename RetVal >
              struct ReturnType {
              bool error;
              union {
              RetVal * retval;
              Error * error;
              };
              };

              ReturnValue < Person > ParseXML(string XML) ...
              @

              Ivan Čukić | ivan.cukic(at)kde.org | KDE e.V.
              Qt Ambassador (from the old Nokia days)

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved