Cutton Eye Cutton Eye - 21 days ago 5
C++ Question

Passing default string pointer to function

there is a prototype of a function in my fuu.h. I want to pass default values if there

void MyFunction(
int iError = 0,
std::string * MyProblemString = ""
);

// Some attemts:

void MyFunction(
int iError = 0,
std::string * MyProblemString = std::string{""}; // does not work to, complains about missing '*'
);

void MyFunction(
int iError = 0,
std::string * MyProblemString = &std::string{""}; // does not work to, refering address to temporary value
);

void MyFunction(
int iError = 0,
std::string * MyProblemString = *std::string{""}; // does not work to, overloaded operator not known
);

void MyFunction(
int iError = 0,
std::string * MyProblemString = ""; // could not convert ‘""’ from ‘const char [1]’ to ‘std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}’
);

in my c-file is written:

void MyFunction(
int iError,
std::string * MyProblemString,)
{
// do some stuff
}


With the int it's working fine. How can I make the same thing with the string?

There are some examples with other constructions, but passing a pointer does not work.
const reference default-value

thx

Answer

The problem you are having is because you can't give a default value to a pointer without dealing with the memory the pointer is supposed to point to. If you use a std::string instead of a pointer to std::string then you can use the simple string literal syntax as in MyFunction().

If you need to pass a pointer to a string, because you are planning to manipulate the string or for some other purpose, you can give the string the default value of NULL. Since NULL does not point to any memory, this is a perfectly sane default for a pointer. Then you can check for this value, and allocate a new std::string in that special case. That is what I am doing in MyFunction2.

HOWEVER if you allocate memory, you must free that memory somewhere. In my example, I am freeing the memory inside of MyFunction2 only if I also created it. If the value was supplied, I am not freeing the value, but rather leaving that up to the calling function. How you manage memory will depend on your use case, but don't forget about this crucial step.

#import <iostream>

void MyFunction(
    int iError = 1,
    std::string MyProblemString = std::string(""))
{
  std::cout << "\tiError = " << iError << ", and MyProblemString = " << MyProblemString << std::endl;
}

void MyFunction2(
    int iError = 1,
    std::string * MyProblemString = NULL)
{
  bool shouldFree = MyProblemString == NULL;
  if (shouldFree){
    MyProblemString = new std::string("");
  }
  std::cout << "\tiError = " << iError << ", and MyProblemString = " << *MyProblemString << std::endl;

  if(shouldFree){
    delete MyProblemString;
  }
}

int main(){
  std::string * test = new std::string("test");

  std::cout << "Testing with MyFunction:" << std::endl;
  std::cout << "\tTest default arguments:" << std::endl;
  MyFunction();

  std::cout << "\tTest only first argument:" << std::endl;
  MyFunction(0);

  std::cout << "\tTest both arguments" << std::endl;
  MyFunction(2, *test);

  std::cout << std::endl;

  std::cout << "Testing with MyFunction2:" << std::endl;
  std::cout << "\tTest default arguments:" << std::endl;
  MyFunction2();

  std::cout << "\tTest only first argument:" << std::endl;
  MyFunction2(0);

  std::cout << "\tTest both arguments" << std::endl;
  MyFunction2(2, test);

  delete test;
}