C++ Logo

std-proposals

Advanced search

Simple Beautification and readability open for template classes

From: Chris Green <aachrisg_at_[hidden]>
Date: Thu, 15 Oct 2020 18:37:40 -0700
I have been working on a set of tools and settings for improving the
readability, documentability, and aesthetics of c++, mainly through IDE
efforts. You can get pretty far with current existing tools and a few good
macros and conventions.

Looking at the readability of header files defining template classes (for
instance, std::), It's clear to me that the template declarations are
really hindering readability. Not just because of their syntax, but they
cause there to be SO MUCH text between the start of the declaration and the
thing you are declaring. Here is an example from microsoft's
implementation of std::span from github. I picked std::span because
conceptually it should be fairly simple.
Here is the actual class declaration, viewed as plain text:

template <class _Ty, size_t _Extent = dynamic_extent> class span : private
_Span_extent_type<_Ty, _Extent> {

It's basically impossible to tell at a glance what that is even
declaring (the 'span' class). Loading it into an editor with
colorization doesn't make it any better, maybe even worse:

[image: image.png]

My proposal is that the abbreviated syntax for defining template
functions without 'template' be extended to classes. The 'class'
declaration statement shall allow a templated argument list enclosed
in angle brackets immediately after the name of the new identifier.
This shall be equivalent in all ways to adding the "template" keyword
before the definition, with the chosen arguments.


  class span<class _ElementType, size_t+ _Extent = dynamic_extent> :
private pan_extent_type<_ElementType, _Extent>


I would also propose the following, which also helps readability of
header files, but also solves the "namespace indentation problem"
without macros, and saves you from typing prototypes twice:

- When declaring something at global scope outside of an active
namespace{ block, an existing namespace name may be placed at the
beginning of the identifier followed by ::. This will have the effect
of inserting the declaration into that namespace as if the block had
been surrounded by a namespace{ block:

   class std::span<class _ElementType, size_t _Extent =
dynamic_extent> : private _Span_extent_type<_ElementType, _Extent> {

This has the benefit effect that the name of the thing being declared
really stands out now, and when you see the prototype, you know
exactly where it is. You cannot tell at all what namespace this class
is in by examining the header file as is, because:
    - you'd have to look backward for a namespace declaration
    - you wouldn't guess that it was inside of one because there is no
indentation, because indenting for namespace blocks sucks and obscures
the scope of the declaration.
    - there's no namespace declaration at all! Because indentation
sucks in namespace blocks, this file uses a preprocessor macro
instead, _STD_BEGIN. You would have to look at the definition of this
macro to figure out that span is std::span

This has no compatibility with existing code, as it is an error to do
this in c++20.

[image: image.png]

Now, the name of the class, what namespace it is is prominently at the
beginning, and the declaration is just plain shorter, without losing
any capabilities.

There are other possibilities in the same vein:

Could:

template <typename T> concept bool HasFunc1 = requires(T t) { {
t.func1() } -> int;};

Received on 2020-10-15 20:37:54