-1

I have a function in a C++ program returning a string. On certain conditions, e.g. if the function encounters an error or so, I want to return a special value telling the caller that something has gone wrong.

I could basically just return an empty string "", but the function does need the empty string as normal return value.

  • How can I accomplish this?
  • Do I have do create a special data structure that for my function that holds a bool if the function was successfully run and a string containing the actual return value?

6 Answers 6

10

This sounds like a usecase for exceptions.

try {
  std::string s = compute();
} catch(ComputeError &e) {
  std::cerr << "gone wrong: " << e.what();
}

If you don't want to or can't use exceptions, you could change the function's interface

std::string result;
if(!compute(result)) {
  std::cerr << "Error happened!\n";
}

Though most often, i've seen the return value is used for the actual result, and an error pointer is passed

bool b;
std::string s = compute(&b);
if(!b) {
  std::cerr << "Error happened!\n";
}

This has the benefit that you can default the error argument pointer to 0 and code that can ignore the error (because it could live with an empty string return, for example, or if it knows in advance the input is valid) would not need to bother:

std::string compute(bool *ok = 0) {
  // ... try to compute

  // in case of errors...
  if(ok) {
    *ok = false;
    return "";
  }

  // if it goes fine
  if(ok) {
    *ok = true;
  }
  return ...;
}
Sign up to request clarification or add additional context in comments.

2 Comments

What's with that compute(&s)? Is there any reason you didn't change the function's interface to bool compute(std::string &s) and drop the pointer?
@Chris, you are right i think having it by-reference would be nicer. I will change it
4

You can definitely return a pair, although it is klunky.

pair< string, bool > my_method(...) {
  if (a) {
    return make_pair(some_value, true);
  } else {
    return make_pair("", false); // error
  }
}

pair< string, bool > result = my_method(...);
if (result.second) {
  // success
} else {
  // error
}

You can also pass either the bool or the string by reference,

bool my_method(string& s, ...) {
  ...
}

string s;
if (my_method(s, ...)) {
  // success
} else {
  // error
}

or:

string my_method(bool& ok, ...) {
  ok = false; // default
  ...
}

bool ok;
s = my_method(ok, ...));
if (ok) {
  // success
} else {
  // error
}

Comments

1

You could try returning an auto_ptr to a string, but this will cost you an explicit new-ing of a string.

std::auto_ptr<std::string> Foo(int i)
{
    if(i == 0) // Error!
        return std::auto_ptr<std::string>(NULL);
    else // Works.
        return std::auto_ptr<std::string>(new string("Hello world!"));
}

Comments

-1

If it's really something like an error, you should throw an exception. But by reading your question I guess it's not an "exceptional behaviour"?

If that's the case, you have several non-perfect solutions :

  1. Return a structure with the string and a boolean that tells if the function failed (a simple std::pair<> could be enough).
  2. Make your function modify a string parameter provided by reference and return a boolean telling if the function failed.
  3. Make your function a functor/object that have a state. That state would be (at least) a boolean giving the failure or success of the last function call -- that would then be a function call.

3 is IMO bad design, while 2 and 1 are unperfect compromise.

Comments

-1

It depends on how is your program organized.

You may return an additional boolean signifying if the function succeeded. You may return a structure containing boolean and string. You may return a special string (not necessarily empty) which should represent the failure. You may throw an exception. You may set a global flag indicating an error (though I would not recommend it).

There must be lot of other methods to express function failure, too.

Comments

-1

The std::pair<> method is good. Another alternative is to have the caller pass the output string in as a non-const reference, and have the function return true or false depending on if an error was encountered or not.

bool Foo(int i, std::string& result)
{
    bool ret = false; // no error
    // do stuff...
    result = "blahbalhbalh";
    return ret;
}

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.