Here's another way in which C++ sucks:

After 30 years of professional C++ experience, I'm still confused by these the subtle difference between function overload resolution (which performs implicit conversion) and template argument deduction (which works with exact types).

#cpp sucks #programming

Before someone suggests circumventing the issue with a
dynamically-sized std::span: the original code had two spans of different types, and I wanted to enforce them being the same size at the interface level:

void decode(span<uint32_t, N> in, span<int32_t, N> out);

A coworker suggested a clever solution. Can you guess it?

#cpp #programming

Show thread

@codewiz Template argument deduction is a simple substitution and it is happens before overload resolution, it's only subtle if you forget what it is.

You shouldn't rely on (or think in terms of) conversions to write generic code like this. You are asking the compiler to deduce the size of the span from the size of the array when you never told it those things are connected. The type conversion do not define such a connection, because they are rather free form and can be impossible to reason about in the general case, even if simple cases seem obvious (like you can have type constraints on them and the compiler will have to go through all possible template arguments).

The proper way to associate types that have different interfaces, but are the same in concept, is a traits type (like iterator_traits).
You could probably do the same with less boilerplate and idk concepts might help too, but that's the gist of it. You can specialize the traits type for as many types as you want without them being aware of each other or your generic functions.

Sign in to participate in the conversation
Qoto Mastodon

QOTO: Question Others to Teach Ourselves
An inclusive, Academic Freedom, instance
All cultures welcome.
Hate speech and harassment strictly forbidden.