Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

#define as a workaround for missing concepts

Is this a good idea for a library implementer to define macro while we are waiting for (hopefully) incoming concepts? What are advantages and disadvantages of this approach?

Examples of macro (by A. Stepanov):

#define TotallyOrdered typename
#define Pointer typename
#define Number typename
#define Unsigned typename
#define Integral typename
#define InputIterator typename
#define OutputIterator typename
#define ForwardIterator typename
#define BidirectionalIterator typename
#define RandomAccessIterator typename
...

Example usage (from me):

template<ForwardIterator It>
It min_element(It first, It last) { ... }

The idea:

  • while there are no concepts it's a plain old template code
  • when concepts will finally arrive, you can delete all macros or rename them if concepts names will differ (you can do this easily in any decent IDE) and then delete or just reimplement these macro into concepts expressions
  • take an advantage of future features without rewriting complicated templated code
  • even now, "typed" template parameters allow for better code understanding and unlock a possibility to develop static concept-checking tools

The long story: There are several series of courses by A. Stepanov at Amazon A9 where he uses those macro to substitute typename keyword in template parameters lists of the algorithms implemented in the classroom. Charmed by this "pointer-oriented programmer" and an old guru of all C++ libraries I started to use those macro everywhere. Recently I was pointed out that macro are ugly (and, also, that iterators are kinda obsolete, but this is another story). So now I'm looking for other experts suggestions on this approach.

Examples of libraries in question: a GPU-accelerated version of Standard library (with hight perf computing stuff like structs of arrays, zipped iterators etc.) , a linear algebra library, a tree-like data structure, new algorithm functions

like image 647
Ivan Aksamentov - Drop Avatar asked Feb 09 '23 04:02

Ivan Aksamentov - Drop


2 Answers

One massive disadvantage is that your code will be lying.


What I prefer

The code does not use concepts at all, but you can alter it to use them in the future if/when they exist.

What I don't prefer

The code does not use concepts at all, but looks like it does. Can't imagine anything much more dangerous than this. What a massive sense of false security that's going to imbue upon maintainers!


Your idea won't work anyway. When concepts come along, you'll inevitably discover that you've made some mistakes somewhere that couldn't possibly have been diagnosed by your older compiler. You're still going to have to change your code.

For now, just document the preconditions/constraints for your types, as you've always done.

like image 178
Lightness Races in Orbit Avatar answered Feb 12 '23 21:02

Lightness Races in Orbit


As others have said, this does not sound like a good idea. The standard often uses the name of the template argument to describe the properties it's expected to have. So, for example, the algorithm all_of is described as

template <class InputIterator, class Predicate>
bool all_of(InputIterator first, InputIterator last, Predicate pred);
like image 28
Pete Becker Avatar answered Feb 12 '23 20:02

Pete Becker