This question already has answers here:
no operator "<<" matches these operands [duplicate]
(3 answers)
Closed 6 years ago.
I have this function:
void strPointerTest(const string* const pStr)
{
cout << pStr;
}
If I call it like this:
string animals[] = {"cat", "dog"};
strPointerTest(animals);
it returns the address of the first element. So I was expecting if I dereference it, I'd get the 1st element of the array but doing so like this:
void strPointerTest(const string* const pStr)
{
cout << *(pStr);
}
It won't even let me compile. I tried this using int instead of string and it works. Is there something special with strings? How would I retrieve the elements of the string array in this function?
EDIT:
Here's a complete example and it won't compile on my end:
#include <iostream>
void strPointerTest(const std::string* const pStr);
void intPointerTest(const int* const pInt);
int main()
{
std::string animals[] = { "cat", "dog" };
strPointerTest(animals);
int numbers[] = { 9, 4 };
intPointerTest(numbers);
}
void strPointerTest(const std::string* const pStr)
{
std::cout << *(pStr);
}
void intPointerTest(const int* const pInt)
{
std::cout << *(pInt);
}
I don't know why the downvote. I'm asking for help because it won't compile on my end. If it works on your end doesn't mean it also works on mine. I'm asking for help because I don't know what's happening.
The compilation error is:
No operator "<<" matches these operands - operand types are: std::ostream << const std::string
On some compilers <iostream>happens to also include the <string> header. On other compilers, specifically the Microsoft compiler, it apparently does not. And the I/O operators for strings are declared in the <string> header.
It is your responsibility to include all the needed headers, even if the code sometimes happen to work anyway.
So the fix is to just add
#include <string>
at the top of the file.
Related
I have what is hopefully a trivial question that someone can explain to me in simpler terms than what I have already come across. While working through
A Tour of C++ (Second Edition)
I've been trying a few examples.
I'm currently trying to modify a pointer to a string literal in a separate function (I thought it would be easy.....).
using namespace std;
void test(char *ptr)
{
ptr = "test";
}
int main()
{
char *p = "abc";
test(p);
cout << p << "\n";
return 0;
}
When using g++ to compile, I get a
Warning: ISO C++ forbids converting a string constant to char*
Apparently g++ is auto-converting *p to a const? Surely I'm missing something basic, but my previous SO and google searches have gotten me no closer to the answer. Thank you for your responses!
EDIT:
Both great examples below. Thank you everyone for your responses, very helpful!
Apparently g++ is auto-converting *p to a const?
Quite the opposite. The string "abc" will be in your binary, and that is supposed to be readonly for your program. Therefore, that string should only be read, and the value you get when assigning the string literal in this situation is of type const char*. You get the error because you're assigning it to a non-const char*. Try this instead:
const char *p = "abc";
Also, you'll have to change the function, too:
void test(const char *ptr)
{
ptr = "test";
}
It's still going to print abc, however. That's because you're only modifying a copy of the value that you're passing. But C++ lets you pass a reference instead, which you can do like this:
void test(const char *&ptr)
{
ptr = "test";
}
Now that's a reference to a pointer pointing to a const char... whew! Both the "abc" and "test" will be in the program's binary when it is compiled. When the program is run, the address of "abc" is assigned to char *p, and then the function to change it to have the address of "test" instead is called. The & tells it to work with the actual char *p and not just a copy of it that gets lost when the function finishes.
There are two things that can be const; the pointer (char * const), or the object (const char *).
The string literal is const, that's what the compiler is complaining about. You should use
const char *p = "abc";
The function would still not modify the pointer p from main() though, because it is passed by value to the function.
This should modify the pointer:
using namespace std;
const char * str2 = "test";
void test(const char *& ptr)
{
ptr = str2;
}
int main()
{
const char *p = "abc";
test(p);
cout << p << "\n";
return 0;
}
live demo
This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Printing C++ int pointer vs char pointer
(3 answers)
Closed 4 years ago.
Keep in mind that my knowledge of pointers is quite small, as I just started learning about them.
While I was messing around in C++, I wrote this small bit of code thinking it would just print out the address of each character in the string
#include <iostream>
using namespace std;
string a = "Hello, World!";
int main() {
for(int i=0; i<a.length();i++) {
cout << &a[i] << endl;
}
return 0;
}
When I compiled and ran this, however, it resulted in it printing as if the string moved to the left.
It just doesn't make sense why when it uses &, which I thought would retrieve the address, would instead get the rest of the string.
As said in the comment, &a[i] is a pointer to a char, and << operator will print null terminated string starting from this character, not its address. So if you want to print the address, you must cast it to void *, as follow :
#include <iostream>
using namespace std;
string a = "Hello, World!";
int main() {
for(int i=0; i<a.length();i++) {
cout << (void *)&a[i] << endl; //cast to (void *) to get the address
}
return 0;
}
string subscript ([]) operator returns char. So & operation returns a pointer to char. And cout operator<< has an overloading for it, which consider it should print out the parameter as a c-string. You should cast it to void* so cout wouldn't think it is a string.
(void*)&a[i]
This question already has answers here:
Printing array element memory adresses C and C++, why different output? [duplicate]
(4 answers)
Closed 6 years ago.
Refer the code below:
#include <iostream>
class Boy {
char name[10];
public:
void show() {
*name = 0;
std::cout << "\n" << &name[0];
}
};
int main() {
Boy b;
b.show();
}
Here, why don't we see the address of name[0]. I also tried with name, which itself is address. Still I can't see the address, it returns blank screen.
It's because you're using char* overload for operator<<, which treats the pointer as a pointer to c-string. Cast your pointer to void* to print it as such.
std::cout << "\n" << static_cast<void*>(&name[0]);
This question already has answers here:
Passing an array as an argument to a function in C
(11 answers)
Closed 7 years ago.
I read here:
C: differences between char pointer and array
that char pointers and char arrays are not the same. Therefore, I would expect these to be overloading functions:
#include <iostream>
using namespace std;
int function1(char* c)
{
cout << "received a pointer" << endl;
return 1;
}
int function1(char c[])
{
cout << "received an array" << endl;
return 1;
}
int main()
{
char a = 'a';
char* pa = &a;
char arr[1] = { 'b' };
function1(arr);
}
Yet upon building I get the error C2084: function 'int function1(char *)' already has a body. Why does the compiler seem to consider a char pointer to be the same as a char array?
Because when you pass an array into a function, it magically becomes a pointer.
Your two functions, then, are the same.
The following are literally* identical:
void foo(int arr[42]);
void foo(int arr[]);
void foo(int* arr);
(* not lexically, of course :P)
This historical C oddity is the major reason lots of people mistakenly think that "arrays are pointers". They're not: this is just a bit of an edge case that causes confusion.
This question already has answers here:
initialize a const array in a class initializer in C++
(10 answers)
Closed 9 years ago.
I need to initialize a const int array in a class constructor via initialization list in C++.
I know that there is an easy solution of this problem based on using
extended initialization list.
Still, I want to avoid using -std=c++11 or -std=gnu++11.
Obviously, I know from the beginning that its size is 4 and the
content is {1, 2, 3, 4}.
The only way I can conceive doing this while staying out of the C++11 initializer list realm is to bury it in a struct wrapper and value-initialize it in your construct-initializer list:
#include <iostream>
using namespace std;
struct ArrayWrap
{
int content[4];
int& operator [](size_t n) { return content[n]; }
int operator [](size_t n) const { return content[n]; }
};
static const ArrayWrap content = { {1,2,3,4} };
struct MyObj
{
const ArrayWrap arrwrap;
MyObj() : arrwrap(content) {}
};
int main(int argc, char *argv[])
{
MyObj obj;
for (int i=0;i<4;++i)
cout << obj.arrwrap[i] << ' ';
cout << endl;
return EXIT_SUCCESS;
}
Output
1 2 3 4
It is common in C to bury fixed arrays in structures when returning them from functions by value, and in this case I'm simply exploiting the default copy-ctor of the wrapper struct as-generated by the C++ compiler.
Probably not the ideal solution for what you want, but it does work, and compiles under C++98.
Well, if you're banning C++11 solutions from the candidate set, then you simply cannot do this.