2

I'm writing my own string class StringEx in c++ (don't worry, just for exercise) but I'm failing at creating an instance of my class by assigning a string to it:

StringEx string1 = StringEx("test"); // works fine
StringEx string2 = "test"; // doesn't work

string string3 = "test";
string1 = string3; // also works fine

I overloaded the assignment operator so it can handle with std::string but I have to create an object of StringEx first.

How can I create a new object of StringEx by assigning a string to it? Is it even possible to get c++ handling every "string" as an object of my StringEx class?

This is my StringEx.h which works now

#ifndef STRINGEX_H
#define STRINGEX_H


#include <iostream>
#include <string>
#include <vector>
using namespace std; //simplyfying for now

class StringEx
{
private:
    vector<char> text;
public:
    StringEx();
    StringEx(string);
    StringEx(const char*);  // had to add this
    StringEx(vector<char>);

    int size() const;
    int length() const;
    char at(int) const;

    void append(const string&);
    void append(const StringEx&);
    void append(const char*);  // had to add this

    StringEx operator+(const string&);
    StringEx operator+(const StringEx&);
    StringEx operator+(const char*);  // had to add this too

    StringEx operator=(const string&);
    StringEx operator=(const StringEx&);
    StringEx operator=(const char*);  // had to add this too

    StringEx operator+=(const string&);
    StringEx operator+=(const StringEx&);
    StringEx operator+=(const char*);  // had to add this too

    friend ostream& operator<<(ostream&, const StringEx&);
};

#endif // STRINGEX_H
8
  • This is called initialization (more precisely, copy-initialization), not assignment. Assignment is when the object was already previously constructed (like in your last example). Commented Sep 2, 2015 at 8:57
  • Strangely enough: This code compiles just fine with VS2015 Commented Sep 2, 2015 at 9:09
  • You've already got some answers, but you really should show the declaration of your class's constructors, copy constructors and copy assignments. Commented Sep 2, 2015 at 9:15
  • @SimonKraemer MSVC has never been a paragon of standards compliance. Commented Sep 2, 2015 at 9:18
  • 1
    @LPrulzcrossover Your edit shows the StringEx.h that caused the error, or the StringEx.h that works now? Please edit your question and explain what you are showing. Commented Sep 2, 2015 at 9:24

3 Answers 3

7

A few precisions:

StringEx string1 = StringEx("test"); // works fine

This use the copy-constructor, i.e. StringEx(const StringEx& other);

StringEx string2 = "test"; // doesn't work

This tries to use a constructor with the following signature: StringEx(const char* str);

Finally, those two lines:

string string3 = "test";
string1 = string3; // also works fine

create an std::string from a const char*, which the standard library defines, and then use the copy-assignment operator overloaded for std::string that you seem to have defined correctly, i.e. StringEx& operator=(const std::string& other).

The key point here is that this statement:

Type myVar = something;

is not an assignement, it's an declaration and initialisation of a variable which uses a constructor, not the copy-assignment operator.

In your case, you're just missing a constructor that takes a const char* as parameter.

Sign up to request clarification or add additional context in comments.

5 Comments

The original code can be compiled with MSVC14/VS2015 and works just fine. Even though the IDE shows an error.
Thanks, works now! Is it possible to get c++ handling every const char* as a StringEx? In order to get i.e. cout << "hello" + "world"; work.
@LPrulzcrossover You can't implicitly (well, maybe you could in a very ugly way that I'm not aware of). Why would you want that anyway? That line can work with a proper overload of operator+ for two const char* that returns an std::string for example.
Is it even possible to overload operator+ for two const char*? Considering this it seems like the answer is no, or how would you do that?
Should've checked before, it's actually not possible. C++ Standard at §13.5.6 specifies that at least one of the parameters type must be a class, a reference to a class, an enumeration, or a reference to an enumeration, when overloading binary operators. My bad.
4

I assume that you have a non-explicit constructor of the form

StringEx (const std::string&);

or similar.

String literals are not of type std::string. "test" is of type const char[5]. std::string has a non-explicit constructor accepting a const char*, so your two calls look like this (not taking copy elision into account):

//implicitly convert "test" to temporary std::string
//construct temporary StringEx with temporary std::string
//copy-construct StringEx with temporary
StringEx string1 = StringEx("test"); 

//no StringEx constructor taking const char*
//two conversions necessary to make "test" into a StringEx
//invalid
StringEx string2 = "test";

An easy fix for this is to add a constructor taking a const char* to StringEx:

StringEx (const char*);

Alternatively you could just use direct initialization:

//only one conversion needed
StringEx string2 ("test");

Comments

3

TLDR: The compiler won't autoresolve if 2 "casts" are necessary. In this case const char* to std::string to StringEx


StringEx string1 = StringEx("test"); // works fine > This calls the constructor explicitly and therefore only one conversion must be done: const char* to std::string.

StringEx string2 = "test"; // doesn't work > This on the other hand is not clear. Do you want to cast const char* to std::string and use the StringEx(const std::string&)constructor or use some other intermediate class?

What you need is another constructor accepting const char* as parameter.

BTW:

StringEx string4 = std::string("test"); //Also works

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.