my class have a string private and i need output string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <string>
#include <string.h>

using namespace std;

class Variant
{
private:

    string result;

public:

    Variant()
    {
    }

    template <typename T>
    Variant(T val)
    {
        result=to_string(val);
    }

    Variant(string val)
    {
        result=val;
    }

    Variant(const char* val)
    {
        result=val;
    }

    Variant(const char val)
    {
        result=val;
    }

    Variant(bool val)
    {
        result=to_string(val);

        if (result=="0")
        {
            result="false";
        }
        else
        {
            result="true";
        }
    }

    friend ostream& operator<< (ostream &out, Variant &VResult)
    {
        out <<VResult.result;
        return out;
    }

    friend istream& operator >> (istream &in, Variant &VResult)
    {
        getline(in,VResult.result);
        return in;
    }

    operator double()
    {
        return atof(result.c_str());
    }

    operator string() //problem
    {
        string b=result;
        return b;
    }

    operator char*()
    {
        char *cstr = new char[result.length() + 1];
        strcpy(cstr, result.c_str());
        return cstr;
    }
};

int main()
{
    string c="hello";
    double i=2100;
    Variant b="dsfgdsfd";
    c=b;
    cout << c;
    return 0;
}

error message: "ambiguous overload for 'operator=' (operand types are 'std::string {aka std::basic_string<char>}' and 'Variant')"
can anyone advice me how to fix the string operator?
You forgot to tell the program how to handle the '=' operator when it is given a string and an instance of your class. Line 71 isn't your problem, it's Line 90 that's causing this error.
Line 77 is the problem.

1
2
3
4
5
6
    operator char*()
    {
        char *cstr = new char[result.length() + 1];
        strcpy(cstr, result.c_str());
        return cstr;
    }


Get rid of this. It's a very bad idea to pass off ownership of dynamically allocated memory in an implicit cast operator. This will cause memory leaks pretty much every time this cast occurs.


The actual error you're getting is because string can be assigned by either another string, or from a char*. Your variant class can be implicitly cast to either of those, so the compiler doesn't know which one you want.

Removing the char* cast operator will not only make it clear that you are casting to a string... but also will avoid the memory leak
sorry, but i want output char* and string too...
now thse code works for char* and string:
1
2
3
4
operator char*()
    {
        return (char *) result.c_str();
    }

but for string i must casting. so what you advice more?
I think you have to get rid of both casts (to string and to char *)

You have 2 cast operators that can start with a Variant and automatically result in a string, but don't forget you're trying to assign a Variant in the first place!

So, in line 90, the question the compiler can't answer is this "Is b a Variant, a const char * or a string?"

I suggest adding functions that return string or const char *, instead of overloading the cast.

P.S. You need to #include <cstdlib> to use atof (suggest using strtod though).
sorry, but can you give me more information?
if i use these:
1
2
3
4
 string& operator=(Variant &Vresult)
    {
        return Vresult.result;
    }

i don't need casting the string(is what i need), but the string isn't returned(don't returns anything) and stays confused with:
1
2
3
4
operator char*()
    {
        return (char *) result.c_str();
    }

sorry if i'm bored you with these, but you have true: i didn't read some information from the books or something :(
but how can i resulve these problem?
Last edited on
If I understand you, you don't need the cast? If so try using non operator members instead:

In public section of class Variant:
1
2
3
4
5
6
7
8
9
10
11
...
char *get_char() const
{
    return const_cast<char *>(result.c_str());
}

string get_string() const
{
    return result;
}
...


Then in main(), you can do
1
2
3
4
5
6
7
8
9
int main()
{
    string c="hello";
    double i=2100;
    Variant b="dsfgdsfd";
    c=b.get_string();
    cout << c;
    return 0;
}


I'm sorry if I've misunderstood you, if that's the case, please try explaining the problem differently.
sorry.. but see these:
1
2
3
4
5
6
7
8
int main()
{
    string c;
    Variant b="fdsgfds";
    c=(string)b;//i want avoid the casting. and i do directly: 'c=b'
    cout << c;
    return 0;
}


1
2
3
4
5
6
7
8
int main()
{
    char *c;
    Variant b="fdsgfds";
    c=b;//like you see it's directly... i want the same for string
    cout << c;
    return 0;
}


sorry my english... i'm trying :(
Last edited on
I see what you're trying to do now, also please ignore my first comment. That was just nonsense. Let's go back to @Computergeek01 -

The problem is that the string operator= accepts both const string& and const char * Variant can be cast to either of them, so how will the compiler decide which one you intend?

Your code for char * works, bacause there's no ambiguity. You can't automatically convert a string to a char *
It doesn't work the other way, because you can automatically convert a char * to a string - this leads to ambiguity.

Even operator double () sill cause a problem here.

Unfortunately, you can't overload operator= globally, which is what I think you would like to do (in terms of functionality).

Bottom line, I'm not sure this can be done this way.
please tell me how can i output string or char* without compilers enter in conflits... please?
yes you have right, now i have tested about the double, and i must use int for fix it ;)

heres how i fix them:
1
2
3
4
5
6
7
8
9
10
11
template<typename T>
    Variant(T val)
    {
        result=to_string(val);
    }

template <typename T>
    operator T()
    {
        return atof(result.c_str());
    }

the templates are for numbers and works...
i did the output be double, because the compiler knows what to do if is long or even int
Last edited on
heres my new code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <string>

using namespace std;

class Variant
{
private:
    string result;

public:
    Variant() : result("")
    {
        ;
    }


    Variant (const double &v)
    {
        result=v;
    }

    Variant(char &v)
    {
        result=v;
    }

    Variant(const char &v)
    {
        result=v;
    }

    Variant(const string &v) : result(v)
    {
        ;
    }

    Variant(const char *v) : result(v)
    {
        ;
    }

    Variant( char *v) : result(v)
    {
        ;
    }

    Variant(bool v) : result(v?"true":"false")
    {
        ;
    }

    template<typename T>
    Variant( T val)
    {
        result=to_string(val);
    }

    friend ostream& operator<< (ostream &out, Variant &v)
    {
        out << v.result;
        return out;
    }

    friend istream& operator>> (istream &in, Variant &v)
    {
        getline (in, v.result);
        return in;
    }

    operator char*()
    {
        return (char*) result.c_str();
    }

    explicit operator int()
    {
        return atoi(result.c_str());
    }

    explicit operator char()
    {
        return (char)'g';
    }
};


int main()
{
    char c='h';
    Variant b =c;
    cout << b << endl;
    c =b;
    cout << c << endl;
    return 0;
}


now the char* and string works fine, but now i'm trying do the char. so how can i explicit the char?
1
2
3
4
explicit operator char()
    {
        return (char)result;
    }

these code needs to be casting, but i need correct that. any advice, please?
Topic archived. No new replies allowed.