Alan Turing
Alan Turing

Reputation: 12581

What's the safest way to define short function name aliases in C++?

Suppose I have a class Utility in a file utility.h:

class Utility {
public:
    static double longDescriptiveName(double x) { return x + 42; }
};

And then I find that I use the function longDescriptiveName(...) a LOT. So like an irresponsible C++ programmer that I am when I've had too much coffee, I create a new file utilitymacros.h and add the following there:

#define ldn Utility::longDescriptiveName

Now I include "utilitymacros.h" in any *.cpp where I use ldn(...) and my heart is filled with joy over how much more convinient it is to type 3 letters vs 28.

Question: Is there a safer (more proper) way of doing this than with #define?

I've noticed that I have to include "utilitymacros.h" after including boost headers, which I obviously don't like because it's a sign of clashes (though the Boost errors I get are not very clear as to what the clash is).

Clarification 1: On Code Readability

In case you might say that this negatively affects code readability, I assure you it does not, because it's a small set of functions that are used A LOT. An example that is widely know is stoi for stringToInteger. Another is pdf for probabilityDensityFunction, etc. So if I want to do the following, stoi is more readable in my opinion:

int x = stoi(a) + stoi(b) + stoi(c) + stoi(d);

Than:

int x = Utility::stringToInteger(a) + Utility::stringToInteger(b)
        + Utility::stringToInteger(c) + Utility::stringToInteger(d);

Or:

int x = Utility::stringToInteger(a);
x += Utility::stringToInteger(b);
x += Utility::stringToInteger(c);
x += Utility::stringToInteger(d);

Clarification 2: Editor Macro

I use Emacs as my IDE of choice and a Kinesis keyboard so you KNOW I use a ton of keyboard macros, custom keyboard shortcuts, as well as actually modifying what I see in the editor vs what's actually stored in the h/cpp file. But still, I feel like the simplicity and visual readability (as argued above) of using a function abbreviation in a few select cases really is the result I'm looking for (this is certainly subject to a degree).

Upvotes: 9

Views: 5820

Answers (6)

jogojapan
jogojapan

Reputation: 70027

I don't know if this helps, but I think part of the problem may be the use of overly general namespaces (or class names, in this case), such as Utility.

If instead of Utility::stringToInteger, we had

namespace utility {
  namespace type_conversion {
    namespace string {
      int to_int(const std::string &s);
    }
  }
}

Then the function could locally be used like this:

void local_function()
{
  using namespace utility::type_conversion::string;

  int sum = to_int(a) + to_int(b) + to_int(c) + to_int(d);
}

Analogously, if classes/structs and static functions are used (and there can be good reasons for this), we have something like

struct utility {
  struct type_conversion {
    struct string {
      static int to_int(const std::string &s);
    };
  };
};

and the local function would look something like this:

void local_function()
{
  typedef utility::type_conversion::string str;

  int sum = str::to_int(a) + str::to_int(b)
              + str::to_int(c) + str::to_int(d);
}

I realize I am not telling you anything about syntax you didn't know already; it's more a reminder of the fact that the organization and structure of namespaces and classes itself plays an important role in making code more readable (and writable).

Upvotes: 3

PatriceG
PatriceG

Reputation: 4063

You can use alias template (since C++11).

  using shortName = my::complicate::function::name;

Upvotes: -1

Kenneth Laskoski
Kenneth Laskoski

Reputation: 135

One alternative is to rename your function and put it in a namespace instead of a class, since it is static anyway. utility.h becomes

namespace Utility {
    // long descriptive comment
    inline double ldn(double x) { return x + 42; }
}

Then you can put using namespace Utility; in your client code.

I know there are lots of style guides out there saying short names are a bad thing, but I don't see the point of obeying some style and then circumventing it.

Upvotes: 4

David G
David G

Reputation: 96845

You could use a function reference:

double (&ldn)(double) = Utility::longDescriptiveName;

Upvotes: 7

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361722

Instead of macro, you could write inline function that forwards the call to the actual function:

inline double ldn(double x)
{
   return Utility::longDescriptiveName(x);
}

That is certainly safer than macro.

Upvotes: 15

NYCdotNet
NYCdotNet

Reputation: 4647

How about configuring a snippit/macro/similar thing in your text editor? This way you only have to type ldn or something like that and the code doesn't have to run through the preprocessor risking difficult to find bugs later.

Upvotes: 3

Related Questions