CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 22
  1. #1
    Join Date
    Apr 2009
    Posts
    1,355

    i'm updating my variant type

    (please forget the boost::variant.. i have test it and i give up on it)
    i'm update my class for accept the class's\structs and more.
    see the entire class:
    Code:
    #ifndef VARIANT_H_INCLUDED
    #define VARIANT_H_INCLUDED
    
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    class variant
    {
    private:
        bool blnvoid;
        string a;
        void *b;
    
    public:
    
        variant()
        {
            blnvoid=false;
            a="";
            b=NULL;
    
        }
        variant (string value)
        {
            a=value;
        }
    
        variant (double value)
        {
            a=to_string(value);
        }
    
        variant (int value)
        {
            a=to_string(value);
        }
    
        variant (long value)
        {
            a=to_string(value);
        }
    
        variant (void *value)
        {
            blnvoid=true;
            b=value;
        }
    
        friend istream& operator >>(istream &is,variant &obj)
        {
            is>>obj.a;
            return is;
        } 
    
        friend ostream& operator <<(ostream &os,const variant &obj)
        {
            if (blnvoid==true) //here cames the error and i don't know why :(
            {
                os << obj.b;
            }
            else
            {
                os << obj.a;
            }
            return os;
        }
    
        friend istream &getline(istream &in, variant &s1)
        {
            getline(in, s1.a);
            return in;
        }
    
        variant & operator = (int const & b)
        {
            a=to_string(b);
            return *this;
        }
    
        variant & operator = (long const & b)
        {
            a=to_string(b);
            return *this;
        }
    
        variant & operator = (string const &b)
        {
            a=b;
            return *this;
        }
    
        variant & operator = (double const & b)
        {
            a=to_string(b);
            return *this;
        }
    
        variant & operator = (float const & b)
        {
            a=to_string(b);
            return *this;
        }
    
        bool operator == (string const & b)
        {
            return (a==b);
        }
    
        operator string() const
        {
            return a; // return string member
        }
        operator double() const
        {
            return atof(a.c_str()) ;
        }
    };
    #endif // VARIANT_H_INCLUDED
    error messages:
    - "In function 'std:stream& operator<<(std:stream&, const variant&)':";

    - "error: invalid use of non-static data member 'variant::blnvoid'";

    - "error: from this location".

    i don't understand these errors
    can anyone explain to me?

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: i'm updating my variant type

    if (blnvoid==true) //here cames the error and i don't know why
    blnvoid is a member of the class variant. The function operator<< is not a member of this class and so can't directly access this variable. You are passing obj as a reference to a variant class so use
    Code:
    if (obj.blnvoid == true)
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Apr 2009
    Posts
    1,355

    Re: i'm updating my variant type

    Quote Originally Posted by 2kaud View Post
    blnvoid is a member of the class variant. The function operator<< is not a member of this class and so can't directly access this variable. You are passing obj as a reference to a variant class so use
    Code:
    if (obj.blnvoid == true)
    thanks for correct me... thanks

  4. #4
    Join Date
    Apr 2009
    Posts
    1,355

    Re: i'm updating my variant type

    see these test:
    variant d=100;
    why i get a hexadecimal result with cout?

  5. #5
    Join Date
    Apr 2009
    Posts
    1,355

    Re: i'm updating my variant type

    because i didn't change the blnvoid value
    Code:
    #ifndef VARIANT_H_INCLUDED
    #define VARIANT_H_INCLUDED
    
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    class variant
    {
    private:
        bool blnvoid;
        string a;
        void *b;
    
    public:
    
        variant()
        {
            blnvoid=false;
            a="";
            b=NULL;
    
        }
        variant (string value)
        {
            blnvoid=false;
            a=value;
        }
    
        variant (double value)
        {
            blnvoid=false;
            a=to_string(value);
        }
    
        variant (int value)
        {
            blnvoid=false;
            a=to_string(value);
        }
    
        variant (long value)
        {
            blnvoid=false;
            a=to_string(value);
        }
    
        variant (void *value)
        {
            blnvoid=true;
            b=value;
        }
    
        friend istream& operator >>(istream &is,variant &obj)
        {
            is>>obj.a;
            return is;
        }
    
        friend ostream& operator <<(ostream &os,const variant &obj)
        {
            if (obj.blnvoid==true)
            {
                os << obj.b;
            }
            else
            {
                os << obj.a;
            }
            return os;
        }
    
        friend istream &getline(istream &in, variant &s1)
        {
            getline(in, s1.a);
            return in;
        }
    
        variant & operator = (int const & b)
        {
            a=to_string(b);
            return *this;
        }
    
        variant & operator = (long const & b)
        {
            a=to_string(b);
            return *this;
        }
    
        variant & operator = (string const &b)
        {
            a=b;
            return *this;
        }
    
        variant & operator = (double const & b)
        {
            a=to_string(b);
            return *this;
        }
    
        variant & operator = (float const & b)
        {
            a=to_string(b);
            return *this;
        }
    
        bool operator == (string const & b)
        {
            return (a==b);
        }
    
        operator string() const
        {
            return a; // return string member
        }
        operator double() const
        {
            return atof(a.c_str()) ;
        }
    };
    #endif // VARIANT_H_INCLUDED
    now i can test the the void pointer

  6. #6
    Join Date
    Apr 2009
    Posts
    1,355

    Re: i'm updating my variant type

    is there anyway for test if void pointer type is int\long\double\string?

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: i'm updating my variant type

    A void pointer is a void pointer is a void pointer! Its up to the user of a void pointer to cast it to whatever type they want. If you mean can you test for the type that was originally cast to a void pointer - then no.

    You can, however, do something this like this

    Code:
    #include <iostream>
    using namespace std;
    
    enum vtype {vint, vlong, vdouble};
    
    struct typei {
        vtype vt;
        int myint;
    };
    
    struct typed {
         vtype vt;
         double mydouble;
    };
    
    void processvoid(void *v)
    {
    typei *vp = (typei *)v;
    
    	switch (vp->vt) {
    	case vint:
    		{
    			typei *vi = (typei*) vp;
    			cout << "Got an integer " << vi->myint << endl;
    		}
    		break;
    
    	case vdouble:
    		{
    			typed *vd = (typed*) vp;
    			cout << "Got a double " << vd->mydouble << endl;
    		}
    		break;
    	}
    }
    
    int main()
    {
    typed dou;
    typei ingr;
    
       dou.vt = vdouble;
       dou.mydouble = 23.45;
    
       ingr.vt = vint;
       ingr.myint = 7;
    
    void * v1 = (void*)&dou;
    void * v2 = (void*)&ingr;
    
    	processvoid(v1);
    	processvoid(v2);
    
    	return 0;
    }
    This 'works' because the variable vt is the same in each struct and is always the first element of the struct - so casting the void pointer to any valid type will then allow the value of vt to be determined so that it can then be cast to the correct type based upon the value of vt.

    This method is commonly used with WM_NOTIFY windows message so that different structs can be passed using the same parameter.
    Last edited by 2kaud; November 28th, 2013 at 04:57 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  8. #8
    Join Date
    Apr 2009
    Posts
    1,355

    Re: i'm updating my variant type

    Quote Originally Posted by 2kaud View Post
    A void pointer is a void pointer is a void pointer! Its up to the user of a void pointer to cast it to whatever type they want. If you mean can you test for the type that was originally cast to a void pointer - then no.

    You can, however, do something this like this

    Code:
    #include <iostream>
    using namespace std;
    
    enum vtype {vint, vlong, vdouble};
    
    struct typei {
        vtype vt;
        int myint;
    };
    
    struct typed {
         vtype vt;
         double mydouble;
    };
    
    void processvoid(void *v)
    {
    typei *vp = (typei *)v;
    
    	switch (vp->vt) {
    	case vint:
    		{
    			typei *vi = (typei*) vp;
    			cout << "Got an integer " << vi->myint << endl;
    		}
    		break;
    
    	case vdouble:
    		{
    			typed *vd = (typed*) vp;
    			cout << "Got a double " << vd->mydouble << endl;
    		}
    		break;
    	}
    }
    
    int main()
    {
    typed dou;
    typei ingr;
    
       dou.vt = vdouble;
       dou.mydouble = 23.45;
    
       ingr.vt = vint;
       ingr.myint = 7;
    
    void * v1 = (void*)&dou;
    void * v2 = (void*)&ingr;
    
    	processvoid(v1);
    	processvoid(v2);
    
    	return 0;
    }
    THis 'works' because the variable vt is the same in each strut and is always the first element of the struct - so casting the void pointer to any valid type will then allow the value of vt to be determined so that it can then be cast to the correct type based upon the value of vt.

    This method is commonly used with WM_NOTIFY windows message so that different structs can be passed using the same parameter.
    thanks for that.
    i need change anotherthing:
    variant (void *value)
    the void pointer accept any type, but with variable adress. can i change it for accept the variable name?

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: i'm updating my variant type

    the void pointer accept any type, but with variable adress. can i change it for accept the variable name?
    I'm not sure I understand the question?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #10
    Join Date
    Apr 2009
    Posts
    1,355

    Re: i'm updating my variant type

    Quote Originally Posted by 2kaud View Post
    I'm not sure I understand the question?
    sorry.. i did a mistake... maybe i can see better.. sorry
    see these exemple:

    Code:
    std::vector<int> b;
        b.resize(3);
        b[0]=100;
        b[1]=200;
        b[2]=300;
    variant d=&b;
     cout << d;
    (instead a vector i can use a structure or other)
    please explain better to me the vector and a class for i use with my variant class.. please

  11. #11
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: i'm updating my variant type

    b is a vector of int. So &b is the address of a vector of int. So d is an address of a vector of int. You are trying to assign type of address of a vector of int to a type of class variant. This doesn't work. For it to work, you would need a constructor for class variant that accepted a vector of int. Then you could do variant d = b;

    You could do variant d = (void*)&b; if your variant class had a constructor for a type void *.

    As I said in a previous post, I would avoid using type of void *.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  12. #12
    Join Date
    Apr 2009
    Posts
    1,355

    Re: i'm updating my variant type

    Quote Originally Posted by 2kaud View Post
    b is a vector of int. So &b is the address of a vector of int. So d is an address of a vector of int. You are trying to assign type of address of a vector of int to a type of class variant. This doesn't work. For it to work, you would need a constructor for class variant that accepted a vector of int. Then you could do variant d = b;

    You could do variant d = (void*)&b; if your variant class had a constructor for a type void *.

    As I said in a previous post, I would avoid using type of void *.
    sorry i want avoid the boost::any i have tested.
    Code:
    variant (void *value)
        {
            blnvoid=true;
            b=(void*) &value;
        }
    (i think isn't correct )
    but for use in cout, i must use like another pointer?

  13. #13
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: i'm updating my variant type

    but for use in cout, i must use like another pointer?
    cout must know the type of the argument the value of which it is to display. You can overload the operator << to enable cout to display a type of which it doesn't know already - but in the code for the operator<< function, you will need to know the type of what you are trying to display.

    My previous example in post #7 could be extended for vectors by something like this
    Code:
    #include <iostream>
    #include <vector>
    using namespace std;
    
    enum vtype {vint, vlong, vdouble, vvecint};
    
    struct typei {
        vtype vt;
        int myint;
    };
    
    struct typed {
         vtype vt;
         double mydouble;
    };
    
    struct vecint {
    	vtype vt;
    	vector<int> *pvcti;
    };
    
    void processvoid(void *v)
    {
    typei *vp = (typei *)v;
    
    	switch (vp->vt) {
    	case vvecint:
    		{
    			vecint *vint = (vecint*) vp;
    			cout << "Got a vector of int " << endl;
    			for (vector<int>::const_iterator ci = vint->pvcti->begin(); ci != vint->pvcti->end(); ++ci)
    				cout << *ci << endl;
    		}
    		break;
    
    	case vint:
    		{
    			typei *vi = (typei*) vp;
    			cout << "Got an integer " << vi->myint << endl;
    		}
    		break;
    
    	case vdouble:
    		{
    			typed *vd = (typed*) vp;
    			cout << "Got a double " << vd->mydouble << endl;
    		}
    		break;
    	}
    }
    
    int main()
    {
    typed dou;
    typei ingr;
    vecint tvint;
    
    vector<int> vcint;
    
    	vcint.resize(3);
    	vcint[0] = 100;
    	vcint[1] = 200;
    	vcint[2] = 300;
    
    	tvint.vt = vvecint;
    	tvint.pvcti = &vcint;
    
       dou.vt = vdouble;
       dou.mydouble = 23.45;
    
       ingr.vt = vint;
       ingr.myint = 7;
    
    void * v1 = (void*)&dou;
    void * v2 = (void*)&ingr;
    void * v3 = (void*)&tvint;
    
    	processvoid(v1);
    	processvoid(v2);
    	processvoid(v3);
    
    	return 0;
    }
    Your variant class will probably have to do something similar in order to be able to do what you are trying.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449

    Re: i'm updating my variant type

    Quote Originally Posted by Cambalinho View Post
    sorry i want avoid the boost::any i have tested.
    Why are you playing all of these games with the void pointer?

    All a void pointer knows is that it's a void pointer. There is no "secret way" of detecting what a void pointer is pointing to. That is the bottom line. All you're doing now is coming up with hacks that won't work if someone were to use a type you aren't thinking of. How are you going to handle a vector<double>? A vector<float>? A std::set<int>? A std::map<int, int>? A std::map<double, double>? A Widget? A tuple<int, double, char>? etc. etc. etc. How is your void pointer going to know how to adjust to any type the user comes up with?

    It's pointless for the called function to try and figure out what the variant is pointing to, unless there is an agreement between the caller and called function as to how to specify the type that really is being pointed to. And even then, the use of void pointer isn't needed, as both the called function and the caller knows the available types (You then have the Java-like "god Object" class. If you don't know what I mean, look up the "Object" class in Java, and why most C++ programmers avoid this paradigm).

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; November 28th, 2013 at 09:32 PM.

  15. #15
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: i'm updating my variant type

    But why are you doing all this 'messing about' with void pointers? If you just pass void pointers, then somewhere you are still going to have to decide what type they should be before you do anything useful with them. You can't determine the type that was cast to a void pointer just from having a pointer to void!

    This is where templates come into play. You code one template function or class which can then be used for different types. The template doesn't need to know about the type of which it was called. IMO I would forget about void pointers.
    Last edited by 2kaud; November 28th, 2013 at 06:07 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured