Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: P.1: Express ideas directly in code

43 views
Skip to first unread message

Bo Persson

unread,
Dec 25, 2022, 2:49:37 PM12/25/22
to
On 2022-12-25 at 15:40, Stefan Ram wrote:
> From the code examples for the C++ core guideline
> "P.1: Express ideas directly in code":
>
> |class Date {
> |public:
> | Month month() const; // do
> | int month(); // don't
> | // ...
> |};
>
> . Ok, when I read "int month()", I am not sure whether
> January is 0 or 1, but otherwise I have the idea that
> possible values probably are 0..11 or 1..12 and how to deal
> with them. To learn how to use "Month" takes me at least one
> additional lookup. It could be even more lookups if even
> "Month" then redirects me to more opaque types.
>

What if the return value is January?

https://en.cppreference.com/w/cpp/chrono/month


red floyd

unread,
Dec 25, 2022, 3:39:27 PM12/25/22
to
On 12/25/2022 12:22 PM, Stefan Ram wrote:
> Bo Persson <b...@bo-persson.se> writes:
>> What if the return value is January?
>
> I'd say: If the language actually has a means of indicating
> a month number, then one should use this. I didn't know C++20
> had this!
>
> Using names from the standard library is more clear and
> readable than using names from a custom library would be.
>
> I've started to read the Core Guidelines because it's one
> of the few sources that might already contain a bit of C++20
> (except the ISO standard itself). There are not many books
> for C++20 yet. Lippman, Meyers, Sutter, Stroustrup do not
> seem to have updated their works yet. Today's fast pace of
> standardization puts a strain on authors!
>
>

Josuttis seems to have one out now.

https://www.amazon.com/20-Complete-Guide-Nicolai-Josuttis/dp/3967309207/

Bonita Montero

unread,
Dec 25, 2022, 3:49:03 PM12/25/22
to
mega.nz has a version for free:

https://mega.nz/file/mpcQmSYC#AP0h6VvlX019meVCBQ3Va0m44ptL4L_YrE1V7Eh0Fs0

Password is "usenetrocks".

Alf P. Steinbach

unread,
Dec 27, 2022, 5:31:21 PM12/27/22
to
On 25 Dec 2022 15:40, Stefan Ram wrote:
> From the code examples for the C++ core guideline
> "P.1: Express ideas directly in code":
>
> |class Date {
> |public:
> | Month month() const; // do
> | int month(); // don't
> | // ...
> |};
>
> . Ok, when I read "int month()", I am not sure whether
> January is 0 or 1, but otherwise I have the idea that
> possible values probably are 0..11 or 1..12 and how to deal
> with them. To learn how to use "Month" takes me at least one
> additional lookup. It could be even more lookups if even
> "Month" then redirects me to more opaque types.

Hm, I don't buy that argument. But I would declare the function as

auto month() const -> Month::Enum;

Say no to the newfangled enum classes, they're Just Wrong. Define the
enum like this:

struct Month{ enum Enum{ january = 1, february, ... }; };



> When "const" is missing, this tells me that
> - the function might be effectivly const, but the
> programmer just forgot to mark it correspondingly, or
> - the function may change the object's state.
>
> Would there be a "var", it would tell me clearly that
> - the function may change the object state, it is
> not to be considered "const".

I guess the keyword `mutable` is a little underused and could be set to
work, like they did with `auto`.

However it's not possible to change the defaults, so it would be a
matter of just adding verbosity to express explicitly what would
otherwise be expressed implicitly.


- Alf


David Brown

unread,
Dec 28, 2022, 11:09:35 AM12/28/22
to
On 27/12/2022 23:31, Alf P. Steinbach wrote:
>
> Say no to the newfangled enum classes, they're Just Wrong. Define the
> enum like this:
>
>     struct Month{ enum Enum{ january = 1, february, ... }; };
>
Why?

I can see how it can work, but I have not heard of why it might be
better than enum classes. Can you expand on your reasoning?


JiiPee

unread,
Dec 28, 2022, 2:01:54 PM12/28/22
to
is it that enum Enum converts directly to an integer, as enum class does
not? Easier to use?

Alf P. Steinbach

unread,
Dec 28, 2022, 4:47:42 PM12/28/22
to
Mainly that.

Choosing a class instead of a namespace as container of the enumerator
names is mostly gut-feeling. With class the names can be inherited into
another class, and they can be referred to in a succinct manner via a
local short type alias. With namespace the names can be made available
for unqualified use in a local scope via `using namespace`, or referred
to in a succinct manner via a namespace alias, but not in a class scope.

Classes also become almost /necessary/ to express enum generalizations.
For example, 0 is an Input_stream_id; 1 and 2 are Output_stream_id; and
any Input_stream_id or Output_stream_id is a general Stream_id.
Unfortunately class inheritance goes the wrong way for expressing enum
relationships directly, so in the experimental code below (what a more
concise syntax would have to be translated to) there are just implicit
conversions from Input_stream_id and Output_stream_id to Stream_id:


// struct Input_stream_id{ enum Enum{ in = 0 }; };
// struct Output_stream_id{ enum Enum{ out = 1, err = 2 }; };

class Input_stream_id;
struct Input_stream_id_names
{
static const Input_stream_id in; // 0
};

class Output_stream_id;
struct Output_stream_id_names
{
static const Output_stream_id out; // 1
static const Output_stream_id err; // 2
};

class Input_stream_id:
public Input_stream_id_names
{
const int m_value;

public:
explicit constexpr Input_stream_id( const int value ): m_value(
value ) {}
constexpr operator int() const { return m_value; }
};

class Output_stream_id:
public Output_stream_id_names
{
const int m_value;

public:
explicit constexpr Output_stream_id( const int value ):
m_value( value ) {}
constexpr operator int() const { return m_value; }
};

class Stream_id:
public Input_stream_id_names,
public Output_stream_id_names
{
const int m_value;

public:
explicit constexpr Stream_id( const int value ): m_value( value
) {}

constexpr Stream_id( const Input_stream_id value ): m_value(
value ) {}
constexpr Stream_id( const Output_stream_id value ): m_value(
value ) {}
constexpr operator int() const { return m_value; }
};

inline constexpr Input_stream_id Input_stream_id_names::in
= Input_stream_id( 0 );
inline constexpr Output_stream_id Output_stream_id_names::out
= Output_stream_id( 1 );
inline constexpr Output_stream_id Output_stream_id_names::err
= Output_stream_id( 2 );


- Alf

Juha Nieminen

unread,
Dec 29, 2022, 3:31:27 PM12/29/22
to
Stefan Ram <r...@zedat.fu-berlin.de> wrote:
> From the code examples for the C++ core guideline
> "P.1: Express ideas directly in code":
>
> |class Date {
> |public:
> | Month month() const; // do
> | int month(); // don't
> | // ...
> |};
>
> . Ok, when I read "int month()", I am not sure whether
> January is 0 or 1, but otherwise I have the idea that
> possible values probably are 0..11 or 1..12 and how to deal
> with them. To learn how to use "Month" takes me at least one
> additional lookup. It could be even more lookups if even
> "Month" then redirects me to more opaque types.

Be careful. If you suggest that the method should be named more clearly
and unambiguously, you may run the risk of creating a thousand-post
flamewar thread where people heavily oppose such a ridiculous idea.

Just in case, you should name the method "m()". After all, longer words
make the code harder to undrestand.
0 new messages