The perfect function alias For many years, I have waited for function aliases in C++. They still aren't here. I've been using macros to generate wrapper functions. This is my best attempt at the perfect function alias:

#define FUN_ALIAS(NEW_NAME, ...)                                                \
  template &lt;typename... Args&gt;                                                   \
  inline decltype(auto) NEW_NAME(Args &amp;&amp;... args)                               \
    noexcept(noexcept(__VA_ARGS__(std::forward&lt;Args&gt;(args)...))) {              \
    return __VA_ARGS__(std::forward&lt;Args&gt;(args)...);                            \
  }


I'm using std::forward to forward the arguments and I'm using decltype(auto) to get the right return type. In the future, we might have noexcept(auto) which will be perfect for this situation but I'm not getting my hopes up.

Here's an example from my OpenGL wrapper:

template &lt;GLenum TYPE&gt;
Shader&lt;TYPE&gt; makeShader();
template &lt;GLenum TYPE&gt;
Shader&lt;TYPE&gt; makeShader(const GLchar *, size_t);
template &lt;GLenum TYPE, size_t... SIZES&gt;
Shader&lt;TYPE&gt; makeShader(const GLchar (&amp;... sources)[SIZES]);

FUN_ALIAS(makeVertShader, makeShader&lt;GL_VERTEX_SHADER&gt;)
FUN_ALIAS(makeFragShader, makeShader&lt;GL_FRAGMENT_SHADER&gt;)


What I want to know: 


Is there a situation where the compiler will not optimize away the wrapper because the wrapper and the original function have different semantics?
Does this fail to compile for some functions?
Is there a situation where the compiler will not optimize away the wrapper because the wrapper and the original function have different semantics?


Yes to the first part and no to the second. Any optimizing compiler will inline your wrapper, as it consists of only one return statement.

But on the other hand, the original function might have different semantics: It might be constexpr for example, and your alias will not be.


  Does this fail to compile for some functions?


No (except for the constexpr part).

So here are some improvements you can use:


Templates are implicitly inline, so you don't need to write it explicitly.
Use a lambda to combat the missing constexprness of the alias, because since C++17 lambdas are implicitly constexpr if they can be.


This will get you:

#define FUN_ALIAS(NEW_NAME, ...)                                                \
  inline auto NEW_NAME = [](auto &amp;&amp;... args)                                   \
    noexcept(noexcept(__VA_ARGS__(std::forward&lt;decltype(args)&gt;(args)...)))     \
    -&gt; decltype(auto) {                                                        \
    return __VA_ARGS__(std::forward&lt;decltype(args)&gt;(args)...);                \
  };