Kiamur
Kiamur

Reputation: 125

Working with const std::string pointers as function parameter

after years of writing Java, I would like to dig deeper into C++ again.

Although I think I can handle it, I don't know if I handle it the "state of the art"-way.

Currently I try to understand how to handle std::strings passed as const pointer to as parameter to a method.

In my understanding, any string manipulations I would like to perform on the content of the pointer (the actual string) are not possible because it is const.

I have a method that should convert the given string to lower case and I did quite a big mess (I believe) in order to make the given string editable. Have a look:

class Util
{
  public:
  static std::string toLower(const std::string& word)
  {
    // in order to make a modifiable string from the const parameter
    // copy into char array and then instantiate new sdt::string
    int length = word.length();
    char workingBuffer[length];
    word.copy(workingBuffer, length, 0);

    // create modifiable string
    std::string str(workingBuffer, length);

    std::cout << str << std::endl;

    // string to lower case (include <algorithm> for this!!!!)
    std::transform(str.begin(), str.end(), str.begin(), ::tolower);

    std::cout << str << std::endl;

    return str;
  }
};

Especially the first part, where I use the char buffer, to copy the given string into a modifiable string annoys me. Are there better ways to implement this?

Regards, Maik

Upvotes: 2

Views: 1030

Answers (3)

Walter
Walter

Reputation: 45444

As you must make a copy of the input string, you may as well take it by value (also better use a namespace than a class with static members):

namespace util {

    // modifies the input string (taken by reference), then returns a reference to 
    // the modified string
    inline std::string&convert_to_lower(std::string&str)
    {
        for(auto&c : str)
            c = std::tolower(static_cast<unsigned char>(c));
        return str;
    }

    // returns a modified version of the input string, taken by value such that
    // the passed string at the caller remains unaltered
    inline std::string to_lower(std::string str)
    {
        // str is a (deep) copy of the string provided by caller
        convert_to_lower(str);
        // return-value optimisation ensures that no deep copy is made upon return
        return str;
    }
}

std::string str = "Hello";
auto str1 = util::to_lower(str);
std::cout << str << ", " << str1 << std::endl;

leaves str un-modified: it prints

Hello, hello

See here for why I cast to unsigned char.

Upvotes: 0

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122585

The parameter is const (its a reference not a pointer!) but that does not prevent you from copying it:

 // create modifiable string
std::string str = word;

That being said, why did you make the parameter a const reference in the first place? Using a const reference is good to avoid the parameter being copyied, but if you need the copy anyhow, then simply go with a copy:

std::string toLower(std::string word) { 
    std::transform(word.begin(), word.end(), word.begin(), ::tolower);
    // ....

Remeber that C++ is not Java and values are values not references, ie copies are real copies and modifiying word inside the function won't have any effect on the parameter that is passed to the function.

Upvotes: 7

lenik
lenik

Reputation: 23536

you should replace all this:

// in order to make a modifiable string from the const parameter
// copy into char array and then instantiate new sdt::string
int length = word.length();
char workingBuffer[length];
word.copy(workingBuffer, length, 0);

// create modifiable string
std::string str(workingBuffer, length);

with simple this:

std::string str(word);

and it should work just fine =)

Upvotes: 2

Related Questions