0

(win7; gcc 4.8.2 (cygwin))

The code fragment below yields count error Pointer\\ instead of ( "Pointer" ). Is there anything I can do to get the correct result?

  virtual string toString() const { 
     return "Pointer";
  }
  virtual string write() const {
     string str = "( " + '"' + toString() + '"' + " )";
     return str;
  }; 
3
  • What is producing that error? The compiler? Runtime? Commented Feb 15, 2014 at 17:26
  • Is it possible there is a derived type that is overriding either of thos emethods? Commented Feb 15, 2014 at 17:29
  • @Smac89: No, toString() should be const. Not sure why you suggested making it non-const, especially as that has nothing to do with the problem at hand. Commented Feb 15, 2014 at 17:34

2 Answers 2

4

First, let's clear up a few things:

+-------------+----------------+-----------------------+
| Expression  | Type           | Type as operator arg  |
+-------------+----------------+-----------------------+
|  toString() |  std::string   |  std::string          |
|  "( "       |  char const[3] |  char const*          |
|  '"'        |  char          |  char                 |
+-------------+----------------+-----------------------+

These are not all "strings".

The main issue here is that "( " + '"' does not do what you think it does. "Adding" a char to a const char* does not build a larger string; it adds a number to the string literal's pointer value. In doing this, you make a new pointer that points to… well… nowhere useful. In fact you're invoking undefined behaviour by incrementing the pointer so far.

It's a bit like this:

char const* whatYouAreDoing()
{
   char const* a = "( ";
   char b = '"';

   int c = b;
   assert(c == 34);  // assuming ASCII 
   a += c;           // whoops!

   return a;         // this pointer is now nonsense
}

Generally, if you want to "build" a string, you can use stream formatting:

virtual string write() const
{
   std::stringstream ss;
   ss << "( " << '"' << toString() << '"' << " )";
   return ss.str();
}

Or, in this case, since you actually don't need all those literals, the following will be fine:

virtual string write() const
{
   return "( \"" + toString() + "\" )";
}
Sign up to request clarification or add additional context in comments.

4 Comments

You have to remaind that "( " is not of type std::string but of type const char*. And '"' is of type char so you will increase the pointer const char*. And that's not what you want.
@sleepy42: Actually, string literals have type char const[N]. That aside, is this clearer now?
Completly correct (but in this case the const char[3] of "( " should be converted into a const char* because then an operator+ can be used).
@sleepy42: Yes, as my answer says.
0

You should use a string as first summand and to be safe you also need some braces. Make sure that all summands are strings (maybe after conversion).

Okay, that is not entirely true, also operators like + (std::string&, consts char*) are fine if such things exist. But, I hope you get the idea. You have to make sure that the intended +-operations are used, i.e. that ones from the string-class.

See the following example:

#include <string>
#include <iostream>

using namespace std;

string toString() { 
    return "Pointer";
}
string write() {
    string str = string("( ") + '"' + (toString() + '"') + " )";
    return str;
};

int main()
{
    std::cout << "Test:>>" << write() << "<<\n";
  return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.