Search code examples
c++c++11coding-stylealiasverbose

Is it acceptable practice to alias nested templates like std::vector<std::vector<T>> for readability in a team environment?


I'm aware that C++11 introduced alias templates (which is well-explained in this thread) that makes it simple to reduce verbosity. For example:

#include <vector>
template <typename T>
using vec = std::vector<T>;

int main(){
    vec<vec<int>> my_matrix;
//Do whatever I want to do with this matrix
}

Then I can write vec<vec<int>> instead of std::vector<std::vector<int>>.

This would work for my solo project — less angle-bracket clutter, more concise code.

However, I collaborate on a project with multiple teammates who have varying levels of familiarity with modern C++. The concern is that aliasing too much might make it less obvious that vec<vec<int>> is really std::vector<std::vector<int>>. This may incur potential chaos.

My question:

  1. Is it considered good practice to define such aliases at scale in a team codebase?

  2. How do I minimize confusion, or "Huh, what's a vec?" moments for others who read the code, while still enjoying the shorter notation?

  3. Are there any recommended guidelines, naming conventions, or documentation strategies that help teams handle these aliases effectively?

I'm specifically looking for tips, experiences, or style guidelines from folks who have used alias templates in production with larger dev teams.


Solution

  • It is not only acceptable but should be a good practice. Just as we name classes, the purpose of an alias is to name an abstraction of the underlying type. For your illustrative example:

    template <typename T>
    using Matrix = std::vector<std::vector<T>>;
    

    Using the name Matrix explains the purpose much more than the raw types. This should reduce confusion in a large project with a team of developers.

    It avoids typos since entering is much easier than a big template string.

    Note: Matrix is a poor illustration - not criticizing the OP - because it should be a class with the appropriate behaviors.

    An alias also provides flexibility in implementation. In this case, the underlying container can be changed at the alias definition, avoiding a search through the project for each appearance. For example, changing to a std::set. (Yes, it is inappropriate for Matrix; just an illustration.)

    Note: Most modern IDEs display the underlying types by hovering or provide a quick jump to the definition.

    I even use an alias for simple types to know what data I'm working with: using SumType = uint64_t;.