C++ Logo

std-proposals

Advanced search

Optional braces for function definitions in some contexts

From: Kyle Knoepfel <kyleknoepfel_at_[hidden]>
Date: Thu, 27 Jun 2019 11:29:38 -0500
Here’s an idea I’ve been thinking about a lot regarding functions composed of a single statement, and I’d like your thoughts.

Consider the following function (and associated enumeration):

enum class person {alice, bob, david};
std::string_view greet(person const p)
{
  switch(p) {
  case person::alice: return “Hello Alice.”sv;
  case person::bob: return “What’s up Bob?”sv;
  case person::david: return “(Avoid eye contact)”sv;
  }
}

In such a case, where there is no function-local state, I argue that the outer braces should be unnecessary:

std::string_view greet(person const p)
  switch(p) {
  case person::alice: return “Hello Alice.”sv;
  case person::bob: return “What’s up Bob?”sv;
  case person::david: return “(Avoid eye contact)”sv;
  }

Of course, once someone wants to introduce function-local variables that are otherwise not contained by the statement in the function, then braces are required:

std::string greet(person const p)
  std::string const salutation{“Hi “}; // Error! Two statements in non-braced function definition.
  switch(p) {
  case person::alice: return salutation + "Alice.”;
  case person::bob: return salutation + “Bob.”;
  case person::david: return “(Avoid eye contact)”;
  }

I also run into functions that are defined like:

void print_results(std::vector<Result> const& results)
{
  for (auto const& res : results) {
    std::cout << res << ‘\n’;
  }
}

An arguably better approach would be to do something like:

for_all(results, [](auto const& res){ std::cout << res << ‘\n’; });

but I occasionally run into situations where it may be more convenient to keep the explicit for loop:

void print_results(std::vector<Result> const& results)
  for (auto const& res : results) {
    std::cout << res << ‘\n’;
  }

Or consider the handling of simple member functions:

template <typename T>
class my_dumb_pointer {
  T* ptr_;
public:
  T* get() const noexcept { return ptr_; } // vs
  T* get() const noexcept return ptr_; // Simpler? Not sure.
};

Function definitions with empty bodies would still require braces.

Does this idea seem worth fleshing out? How difficult would it be for implementations to provide, if it was worthwhile?

Thanks very much,
Kyle Knoepfel

Received on 2019-06-27 11:31:31