i need a simple correction about strings

the literal string: "hello world"
it's considered a const char*?
(in some overload operators parameters we must use const char* instead char*... i need understand)
that's why, on functions(even overloading), we must use const char* parameter, instead char* right?
They mean different things.

If you are passing a C-style string to a function and the function is not going to change it, then you should use const char*.

If your are passing a C-style string to a function and the function IS supposed to modify it, you should pass char*.

So, some functions should use const char* and some should use char*. It depends on what the function is doing.
Yes.

You have something that cannot be changed. Immutable. Const. Would you loan it to someone that does not promise that they won't attempt to modify your object?

In U foo( const T * bar );
* the foo promises to you to keep its fingers away from bar
* compiler ensures that foo's implementation maintains that promise


Attempt to modify string literals leads to undefined behaviour.
thank you so much for all to all
thank you so much. now i can create more easy a new class that can accept and return the string, const char* and char*:
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
//strValue it's a string class private member
variant(char *chrValue)
        {
            strValue=chrValue;
        }

        variant(const char *chrValue)
        {
            strValue=chrValue;
        }
variant(char *chrValue)
        {
            strValue=chrValue;
        }

        variant(const char *chrValue)
        {
            strValue=chrValue;
        }

        operator string()
        {
            return strValue;
        }

        operator const char*()
        {
            return strValue.c_str();
        }

        operator char*()
        {
            char *cstr = &strValue[0u];
            return cstr;
        }

readers: the assignment operator use the constructors ;)
thank you so much to all
Last edited on
You have class variant?

You have the two constructors twice?

You don't properly initialize the 'strValue' in your constructors.

Your operators are not "const correct".

&strValue[0u] gives an eerie feeling.
i'm sorry that errors:
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;

bool IsNumeric(string st)
{
	int len = st.length();
	for (int i = 0; i < len; i++) {
		if (int(st[i])<48 || int(st[i]) > 57) {
			return false;
		}
	}
	return true;
}


class variant
{
    private:
        string strValue="";
    public:

        ~variant()
        {
            //nothing;
        }

        variant()
        {
            //nothing;
        }

        variant(const variant &vrValue)
        {
            strValue=vrValue.strValue;
        }

        variant(string strvalue)
        {
            strValue=strvalue;
        }

        variant(char *chrValue)
        {
            strValue=chrValue;
        }

        variant(const char *chrValue)
        {
            strValue=chrValue;
        }

        template<typename number>
        variant(number nbValue)
        {
            strValue=to_string(nbValue);
        }

        friend ostream &operator<<(ostream& osOperator, const variant& vrValue)
        {
            osOperator << vrValue.strValue;
            return osOperator;
        }

        friend istream& operator>>(istream &isOperator, variant &vrValue)
        {
            char chrValue[255];
            isOperator.getline(chrValue,255);
            vrValue.strValue=chrValue;
            return isOperator;
        }

        operator string()
        {
            return strValue;
        }

        operator const char*()
        {
            return strValue.c_str();
        }

        operator char*()
        {
            char *cstr = &strValue[0];
            return cstr;
        }

        operator int()
        {
            if(IsNumeric(strValue))
                return stoi(strValue);
            else
                return 0;
        }

        operator long()
        {
            if(IsNumeric(strValue))
                return stol(strValue);
            else
                return 0;
        }

        operator double()
        {
            if(IsNumeric(strValue))
                return stod(strValue);
            else
                return 0.0f;
        }

        operator float()
        {
            if(IsNumeric(strValue))
                return stof(strValue);
            else
                return 0.0f;
        }
};

variant vrValue[]={100,"hello world", 20, "hey"};

int main()
{
    for(int i=0; i<4; i++)
        cout << vrValue[i] << "\n";
    return 0;
}

1 - yes i did a class variant.. for accept strings and numbers;
2 - 2 constructors twice was a mistake(i did some copys... now heres all);
3 - "You don't properly initialize the 'strValue' in your constructors."
i don't use that method... and not all compilers aren't ok with it;
4 - "Your operators are not "const correct"."
i belive you speak about:
1
2
3
4
5
6
7
operator int()
        {
            if(IsNumeric(strValue))
                return stoi(strValue);
            else
                return 0;
        }

here i don't know if i must use it after parentheses... you can correct me more?
Last edited on
Cambalinho wrote:
the literal string: "hello world"
it's considered a const char*?

nobody seems to have pointed it out explicitly, but it's not any kind of pointer. The type of "hello world" is const char[12], an array of 12 constant chars:

1
2
3
4
5
6
7
#include <iostream>
int main()
{
  std::cout << sizeof "hello world" << '\n'; // prints 12
  for(char c : "hello world") // cannot do that with a pointer
      std::cout << c; 
}


it doesn't have a lot of bearing on your program, but it may come up elsewhere one day.
if i miss something, i accept been corrected ;)
but the compiler see the difference between const char* and char*... and for the literal string i must use the const char* or i will get an error
using const char* or const char[], on functions parameters, it's the same. they are dynamic arrays... using const char[4] it's a static array
Cambalinho wrote:
using const char* or const char[], on functions parameters, it's the same

True, passing an array as a function parameter uses a different syntax entirely.

as I said, it doesn't affect your program since you force array to pointer conversions by presenting constructors that take pointers to char. Just for variety, here's how it would look if you took arrays as function parameters:

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
#include <iostream>
#include <string>
#include <type_traits>
class variant
{
    private:
        std::string strValue = "";
    public:
        // constructor from std::string
        variant(const std::string& strvalue) : strValue(strvalue) {}
        // constructor from char arrays --- note: not pointers ---
        template<std::size_t N>
        variant(const char (&chrValue)[N]) : strValue(chrValue, chrValue+N) {}
        // constructor from everything else (could use an enable_if to make it integers-only)
        template<class N>
        variant(N nbValue) : strValue(std::to_string(nbValue)) {}
   
        friend std::ostream &operator<<(std::ostream& osOperator, const variant& vrValue) {
            return osOperator << vrValue.strValue;
        }
        friend std::istream& operator>>(std::istream &isOperator, variant &vrValue) {
            return std::getline(isOperator, vrValue.strValue);
        }
        // skipping your user-defined conversion functions 
};

variant vrValue[]={100,"hello world", 20, "hey"};

int main()
{
    for(auto& v : vrValue)
        std::cout << v << '\n';
}

live demo: https://wandbox.org/permlink/C7v4qhs2GAJ95UiW

Last edited on
thank you so much for all
3 - "You don't properly initialize the 'strValue' in your constructors."
i don't use that method... and not all compilers aren't ok with it;

Cubbi's code does demonstrate the initializer list syntax:
1
2
3
variant::variant( const std::string& strvalue )
: strValue(strvalue) // member initialization
{} // nothing has to be done in the body 

"not all compilers"?
Yes, it is possible that there still exists compilers that do not support what has been in the C++ Standard for 20 years. Back away from them very slowly. You may call a paleontologist, but do not touch such compilers yourself.

4 - "Your operators are not "const correct"."
i belive you speak about:
1
2
3
4
5
6
7
8
9
10
struct Foo {
  void bar();
  void gaz() const;
};

int main() {
  const Foo foo;
  foo.bar(); // ERROR: foo is const
  foo.gaz(); // ok
}

If a member function does not modify the object, then it should be const so that you can call that member on const objects. None of your operators can be called on const objects, because none of them is const.
cubbi: if i do these:
variant vrValue[]={100.456f,"hello world", 20.45, "hey"};
why the 1st one prints: "100.456001"? why the'1'?
Topic archived. No new replies allowed.