Thread: Multiple types in lists, vectors or arrays.

  1. #16
    Registered User
    Join Date
    Aug 2006
    Posts
    28
    Quote Originally Posted by CornedBee
    Indeed that won't work.

    And no, I didn't mean it that way. I meant a core engine that looks like this:
    Code:
    Call Rpc::createCall(string functionName);
    template<typename T> void Call::setArgument(string argName /*or perhaps an index */, T argValue);
    void Call::submit();
    Calling is rather complicated, but allows for ANY number of arguments. (Your engine won't be generic if it doesn't do that.)
    Code:
    Call call = rpc.createCall("greetWorld");
    call.setArgument("myname", "CornedBee");
    call.setArgument("times", 10);
    call.submit();
    The ease-of-use would come from a tool similar to Axis' wsdl2java that takes a WSDL file and generates a C++ wrapper class from it.
    This is a nice solution. However I will probably stick to the template function. The engine doesnt need to be entirely generic as I know exactly what kind of calls I can expect. It is not designed to be a replacement for existing xmlrpc libraries out there, but an engine that my main program will run on. I am basically porting the program from python so I know what the xmlrpc 'engine' can expect.

    Thanks for the help

  2. #17
    Registered User
    Join Date
    Aug 2006
    Posts
    28
    Okay, i've tried writing a function template to take arguments of varying numbers and types. It didnt go so well. Here is what it looks like..

    Code:
    std::string XmlGbx::parseString(std::string pstr){
        std::string outstr = "<value><string>";
        outstr = outstr + pstr;
        outstr = outstr + "</string></value>\n";
        return outstr;
    }
    
    std::string XmlGbx::parseInt(int pint) {
        std::string istr = intostr(pint);
        std::string outstr = "<value><i4>";
        outstr = outstr + istr;
        outstr = outstr + "</i4></value>\n";
        return outstr;
    }
    
    std::string XmlGbx::parseBool(bool pbool) {
        std::string outstr = "<value><boolean>";
        if (pbool == true) {
           outstr = outstr + "true";
        } else {
           outstr = outstr + "false";
        }
        outstr = outstr + "</boolean></value>\n";
        return outstr;
    }
        
    
    template <typename P>
    std::string XmlGbx::parseParam(P param) {
        if (typeid(param).name == "int"){
            return parseInt(param);
        }
        if (typeid(param).name == "string"){
           return parseString(param);
        }
        if (typeid(param).name == "bool") {
           return parseBool(param);
        }
        std::cout << "could not match type" << std::endl;
        return "failed";
    }
           
    
    std::string XmlGbx::endCall(){
        std::string eCall = eCall + "</params>";
        eCall = eCall + "</methodCall>";
        return eCall;
    }
        
    
    template <typename T1, typename T2, typename T3, typename T4, typename T5>
    std::string XmlGbx::sendCall(std::string meName,T1 param1, T2 param2, T3 param3, T4 param4, T5 param5) {
           //build first part of call..
           std::string call = "<?xml version=\"1.0\" ?>\n";
           call = call + "<methodCall>\n";
           call = call + "<methodName>" + meName + "</methodName>\n";
           call = call + "<params>\n";
           if (param1 == "£$"){
              call = call + this->endCall();
              //int handle = this->SockW.sendout(call);
              return call;
           } else {
              call = call + parseParam(param1);
           }
           if (param2 == "£$"){
              call = call + this->endCall();
              //int handle = this->SockW.sendout(call);
              return call;
           } else {
              call = call + parseParam(param2);
           }
           if (param3 == "£$"){
              call = call + this->endCall();
              //int handle = this->SockW.sendout(call);
              return call;
           } else {
              call = call + parseParam(param3);
           }
           if (param4 == "£$"){
              call = call + this->endCall();
              //int handle = this->SockW.sendout(call);
              return call;
           } else {
              call = call + parseParam(param4);
           }
           if (param5 == "£$"){
              call = call + this->endCall();
              //int handle = this->SockW.sendout(call);
              return call;
           } else {
              call = call + parseParam(param5);
              call = call + this->endCall();
              //int handle = this->SockW.sendout(call);
              return call;
           }
           return call;
    }
    Unfortunately the compiler doesnt like me using typeid on a variable cast as a template. It gives me the following error..
    Code:
    64 C:\xmlgbx\gbx\gbxlib.cpp insufficient contextual information to determine type
    I have decided a cleaner solution would be the following suggested by CornedBee...
    Code:
    Call call = rpc.createCall("greetWorld");
    call.setArgument("myname", "CornedBee");
    call.setArgument("times", 10);
    call.submit();
    ...however the setArgument method will still need to know what type it is processing so it can be properly converted to an xml string. How exactly can I figure out the type that is passed at run-time?

    Quote Originally Posted by Bubba
    You should definitely create some wrapper classes that can handle these objects. Derive them from a common base and place common operations that both objects do in the base. Then you can get more specific in the derived classes.

    With this method of using a common base you can then declare an STL container of the base type and yet be able to add both objects since they are derived from the base. This also is a type-safe implementation of doing exactly what you need.

    I would not use variant or any b/c although the functionality is there it cannot be completely safe no matter who wrote it. In essence, C++ provides a much better answer to the problem.
    I like this idea, however it would mean a lot of work initialising a class for each argument and then initialising a container, then adding each one to the container. Since a lot of these calls will be needed in the final app, I want things to be as un-cluttered as possible. I should probably re-phrase my orginal question to "How do I pass multiple arguments of different types to a single class or function and then process accordingly?"

  3. #18
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> however the setArgument method will still need to know what type it is processing so it can be properly converted to an xml string. How exactly can I figure out the type that is passed at run-time?

    Have different setArgument overloads, one for each type?

  4. #19
    Registered User
    Join Date
    Aug 2006
    Posts
    28
    Quote Originally Posted by Daved
    >> however the setArgument method will still need to know what type it is processing so it can be properly converted to an xml string. How exactly can I figure out the type that is passed at run-time?

    Have different setArgument overloads, one for each type?
    Just found out what that means. Good idea thanks - sorry i'm a newbie to this

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You figure it out at compile time, not run time.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    Registered User
    Join Date
    Aug 2006
    Posts
    28
    Quote Originally Posted by CornedBee
    You figure it out at compile time, not run time.
    Yeah its a tricky concept to grasp after coding scripted languages for all this time. I'm starting to get the hang of it now however

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ Vectors versus normal arrays
    By _izua_ in forum C++ Programming
    Replies: 10
    Last Post: 08-12-2007, 01:59 AM
  2. Stl lists and user defined types
    By figa in forum C++ Programming
    Replies: 8
    Last Post: 03-28-2005, 12:09 PM
  3. multiple inputs of multiple types
    By frontz in forum C Programming
    Replies: 8
    Last Post: 01-19-2004, 02:57 PM
  4. Can multiple linked lists share the same structure?
    By passy in forum C Programming
    Replies: 10
    Last Post: 08-28-2003, 04:38 PM
  5. Parallel Arrays with Multiple Arrays
    By Billye Scott in forum C++ Programming
    Replies: 0
    Last Post: 03-02-2002, 11:14 PM