patterncppMinor
Model of Arithmetic concept for usage as Opaque typedef
Viewed 0 times
conceptopaqueusagetypedefformodelarithmetic
Problem
I have a type that models the Arithmetic concept and use it as an opaque
I've put the code into its own repository along with some tests and would like some eyes taking a look into it.
Note: for opaque
Some examples of usage:
-
Example 1: disabling implicit conversions
-
Example 2: opaque type-defs
arithmetic_type.hpp:
```
#ifndef BOOST_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
#define BOOST_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
////////////////////////////////////////////////////////////////////////////////
#include
#include
////////////////////////////////////////////////////////////////////////////////
namespace boost {
////////////////////////////////////////////////////////////////////////////////
/// \name Index types
///@{
/// \brief Implements an int
typedef (AKA strong typedef, see Note below) in some projects. I've put the code into its own repository along with some tests and would like some eyes taking a look into it.
Note: for opaque
typedef I understand the definition given in N3515.- Prior art exist in
Boost.SerializationBOOST_STRONG_TYPEDEF, where it seems that the opaquetypedefs created model the Arithmetic concept (it is thought to be used for integers) but:
- This is not clearly stated
- It doesn't support C++11 features like
constexpr, and move semantics
- It does not inhibit implicit conversions
- On implicit conversions: I wanted to allow conversions, but prefer them to be explicit. This could be made configurable but I don't think it is worth the trouble.
Some examples of usage:
-
Example 1: disabling implicit conversions
int a{2};
long b{3};
b = a; // works: the implicit conversion is safe
Arithmetic a{2};
Arithmetic b{3};
b = a; // error: implicit assignment requires implicit conversion
b = Arithmetic{a}; // works: explicit construction
b = static_cast>(a); // works: explicit conversion-
Example 2: opaque type-defs
struct Tag1 {};
struct Tag2 {};
using Type1 = Arithmetic;
using Type2 = Arithmetic;
Type1 a{2};
Type2 b{3};
b = Type2{a}; // works: explicit construction
b = static_cast(a); // works: explicit conversion
Type2 c{a}; // works: explicit constructionarithmetic_type.hpp:
```
#ifndef BOOST_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
#define BOOST_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
////////////////////////////////////////////////////////////////////////////////
#include
#include
////////////////////////////////////////////////////////////////////////////////
namespace boost {
////////////////////////////////////////////////////////////////////////////////
/// \name Index types
///@{
/// \brief Implements an int
Solution
Here are some small things you can improve:
-
In the following function:
The
-
The following member should be constexpr
constexpr inlineisn't necessary:constexpralready impliesinline.
-
In the following function:
constexpr friend inline Arithmetic operator+(Arithmetic a,
const Arithmetic& b) noexcept {
return a += b;
}The
friend keyword isn't useful: the only function you are calling is operator+= which is public. This note holds for all your operator@= and for all the operators that do not use private members.operatorandoperator>=are generally implemented in function ofoperator
-
The following member should be constexpr
, not const`:static const bool is_specialized = true;Code Snippets
constexpr friend inline Arithmetic operator+(Arithmetic a,
const Arithmetic& b) noexcept {
return a += b;
}static const bool is_specialized = true;Context
StackExchange Code Review Q#44663, answer score: 5
Revisions (0)
No revisions yet.