Recommended way to have backward compatible concepts in C++20

Viewed 144

I'm fairly new to concepts but I like them so far and wanted to use them in a project. The problem is I also wanted the project to compile with earlier C++ standards. So far I've come up with the following pragmatized solution:

#if ISCPP20
   template<NumT number = double,Index index = int,CoordinateContainer<number> coords>
#else
   template<class number = double,class index = int,class coords>
#endif

where NumT, Index, and CoodinateContainer are defined concepts. The solution works but I don't like the verbosity. Is there a recommended method to introduce concepts into a codebase while not breaking backward compilation compatibility?

1 Answers

As a practical matter, if you want to be able to easily remove concepts from code with a macro check, you should not use any kind of compact concept syntax. That means you should always use explicit requires clauses. This makes the syntax easier to #if around.

If you have overloaded concepts, where multiple definitions exist with more restrictive concepts, that's not something that is easy to just remove. It's a part of your interface that you can pass types with different interfaces and the compiler picks which template gets instantiated through a complex overloading scheme.

So you'll have to use some form of SFINAE to do the equivalent. But exactly what you have to do depends on exactly how you're doing it. In some cases, it can be easy, such as with simple template functions that you might be able to convert to just if constexpr blocks inside a single definition.

But other cases are much more difficult. You can put requires clauses on non-template members of a template class. Doing an equivalent thing with SFINAE is much more difficult.

So how to get the same effect will depend on exactly what effect you're trying to achieve.

Related