Quick Links: |
Provide macros for forward language dialect compatibility. More...
BSLS_KEYWORD_CONSTEXPR | C++11 constexpr keyword |
BSLS_KEYWORD_CONSTEXPR_MEMBER | for static constexpr data members |
BSLS_KEYWORD_CONSTEXPR_RELAXED | C++14 constexpr keyword (Deprecated) |
BSLS_KEYWORD_CONSTEXPR_CPP14 | C++14 constexpr keyword |
BSLS_KEYWORD_CONSTEXPR_CPP17 | C++17 constexpr keyword |
BSLS_KEYWORD_DELETED | C++11 = delete function definition |
BSLS_KEYWORD_EXPLICIT | C++11 explicit for conversion operators |
BSLS_KEYWORD_FINAL | C++11 final keyword |
BSLS_KEYWORD_INLINE_CONSTEXPR | Combination macro for inline constexpr |
BSLS_KEYWORD_INLINE_VARIABLE | C++17 inline keyword for variables |
BSLS_KEYWORD_NOEXCEPT | C++11 noexcept keyword |
BSLS_KEYWORD_NOEXCEPT_AVAILABLE | C++11 noexcept flag |
BSLS_KEYWORD_NOEXCEPT_OPERATOR(expr) | C++11 noexcept operation |
BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...) | C++11 noexcept function qualifier |
BSLS_KEYWORD_OVERRIDE | C++11 override keyword |
BSLS_KEYWORD_NOEXCEPT
is replaced with noexcept
on compilers supporting at least the C++11 language standard, and replaced with nothing on compilers supporting an older (e.g., C++03) standard. The goal is to allow implementation of components such that they can take advantage of some C++11 or later features when compiled with C++11 or later mode enabled while also correctly compiling in C++03 mode. The functionality of the respective features won't be available in C++03 mode. BSLS_KEYWORD_CONSTEXPR
: constexpr
when compiling with C++11 or later mode and inserts nothing when compiling with C++03 mode.BSLS_KEYWORD_CONSTEXPR_MEMBER
: constexpr
when compiling with C++11 or later mode and inserts the keyword const
when compiling with C++03 mode. This macro is intended to support declaring static data members.BSLS_KEYWORD_CONSTEXPR_RELAXED
: BSLS_KEYWORD_CONSTEXPR_CPP14
instead. This macro inserts the keyword constexpr
when compiling with C++14 or later mode and inserts nothing when compiling with C++03/C++11 mode.BSLS_KEYWORD_CONSTEXPR_CPP14
: constexpr
when compiling with C++14 or later mode and inserts nothing when compiling with C++03/C++11 mode. See Example 2 below for a better description of the differences between constexpr
between C++11, C++14, and C++17.BSLS_KEYWORD_CONSTEXPR_CPP17
: constexpr
when compiling with C++17 or later mode and inserts nothing when compiling with C++03/C++11/C++14 mode. See Example 2 below for a better description of the differences between constexpr
between C++11, C++14, and C++17.BSLS_KEYWORD_DELETED
: = delete
when compiling with C++11 or later mode and inserts nothing when compiling with C++03 mode.BSLS_KEYWORD_EXPLICIT
: explicit
when compiling with C++11 or later mode and inserts nothing when compiling with C++03 mode.BSLS_KEYWORD_FINAL
: final
when compiling with C++11 or later mode and inserts nothing when compiling with C++03 mode.BSLS_KEYWORD_INLINE_CONSTEXPR
This macro inserts the keywords inline constexpr
when compiling with C++17 or later mode and inserts the best approximation in earlier dialects, ultimately degrading down to static const
in C++03.BSLS_KEYWORD_INLINE_VARIABLE
This macro inserts the keyword inline
when compiling with C++17 or later mode and inserts nothing when compiling with C++03/C++11/C++14 mode.BSLS_KEYWORD_NOEXCEPT
: noexcept
when compiling with C++11 or later mode and inserts nothing when compiling with C++03 mode.BSLS_KEYWORD_NOEXCEPT_AVAILABLE
: true
when the noexcept
feature is available and false
otherwise.BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BOOL_EXPRESSION)
: noexcept(BOOL_EXPRESSION)
when compiling with C++11 or later mode and inserts nothing when compiling with C++03 mode. This macro is used to specify which version of noexcept is intended when multiple noexcept
s are used in a single statement.BSLS_KEYWORD_NOEXCEPT_OPERATOR(expr)
: noexcept(expr)
when compiling with C++11 or later mode and inserts the literal false
when compiling with C++03 mode.BSLS_KEYWORD_OVERRIDE
This macro inserts the keyword override
when compiling with C++11 or later mode and inserts nothing when compiling with C++03 mode.explicit
keyword to indicate that constructors taking just one argument are not considered for implicit conversions. Instead, they can only be used for explicit conversions. C++ also provides the ability to define conversion operators but prior to C++11 these conversion operators are considered for implicit conversion. C++11 allows the use of the explicit
keyword with conversion operators to avoid its use for implicit conversions. The macro BSLS_KEYWORD_EXPLICIT
can be used to mark conversions as explicit conversions which will be checked when compiling with C++11 mode. For example, an Optional
type may have an explicit conversion to bool
to indicate that the value is set (note the conversion operator): template <class TYPE> class Optional { TYPE* d_value_p; public: Optional(): d_value_p() {} explicit Optional(const TYPE& value): d_value_p(new TYPE(value)) {} ~Optional() { delete d_value_p; } // ... BSLS_KEYWORD_EXPLICIT operator bool() const { return d_value_p; } };
Optional
class in a condition it is desirable that it converts to a bool
: void testFunction() { Optional<int> value; if (value) { /*... */ }
#if BSLS_COMPILERFEATURES_CPLUSPLUS < 201103L bool flag = value; #endif }
error: cannot convert 'Optional<int>' to 'bool' in initialization
bool
for code which needs to compile with C++03 mode the conversion operator should convert to a member pointer type instead: doing so has a similar effect to making the conversion operator explicit
. final
keyword after the class name in the class definition to label classes which are not intended to be derived from. The macro BSLS_KEYWORD_FINAL
is replaced by final
when compiling with C++11 causing the compiler to enforce that a class can't be further derived. The code below defines a class which can't be derived from: class FinalClass BSLS_KEYWORD_FINAL { int d_value; public: explicit FinalClass(int value = 0): d_value(value) {} int value() const { return d_value; } };
#if BSLS_COMPILERFEATURES_CPLUSPLUS < 201103L class FinalClassDerived : public FinalClass { int d_anotherValue; public: explicit FinalClassDerived(int value) : d_anotherValue(2 * value) { } int anotherValue() const { return d_anotherValue; } }; #endif
error: cannot derive from 'final' base 'FinalClass' in derived type 'FinalClassDerived'
final
. The macro BSLS_KEYWORD_FINAL
can also be used for this purpose. To demonstrate the use of this keyword first a base class with a virtual
function is defined: struct FinalFunctionBase { virtual int f() { return 0; } };
f
can be marked as the final overrider using BSLS_KEYWORD_FINAL
: struct FinalFunctionDerived: FinalFunctionBase { int f() BSLS_KEYWORD_FINAL { return 1; } };
f
, i.e., the following code will result in an error when compiling with C++11 mode: #if BSLS_COMPILERFEATURES_CPLUSPLUS < 201103L struct FinalFunctionFailure: FinalFunctionDerived { int f() { return 2; } }; #endif
error: virtual function 'virtual int FinalFunctionFailure::f()' error: overriding final function 'virtual int FinalFunctionDerived::f()'
override
is used to identify functions overriding a virtual
function from a base class. If a function identified as override
does not override a virtual
function from a base class the compilation results in an error. The macro BSLS_KEYWORD_OVERRIDE
is used to insert the override
keyword when compiling with C++11 mode. When compiling with C++03 mode it has no effect but it both cases it documents that a function is overriding a virtual
function from a base class. To demonstrate the use of the BSLS_KEYWORD_OVERRIDE
macro first a base class is defined: struct OverrideBase { virtual int f() const { return 0; } };
OverrideBase::f
in a derived class the BSLS_KEYWORD_OVERRIDE
macro should be used to ascertain that the function in the derived class is indeed overriding a virtual
function: struct OverrideSuccess: OverrideBase { int f() const BSLS_KEYWORD_OVERRIDE { return 1; } };
const
in the function declaration): #if BSLS_COMPILERFEATURES_CPLUSPLUS < 201103L struct OverrideFailure: OverrideBase { int f() BSLS_KEYWORD_OVERRIDE { return 2; } }; #endif
error: 'int OverrideFailure::f()' marked 'override', but does not override
constexpr
keyword to indicate that a (very simple) function may be evaluated compile-time if all its input is known compile time. C++14 allows more complex functions to be constexpr
. Also, in C++14, constexpr
member functions are not implicitly const
as in C++11. Thefore we have a separate macro BSLS_KEYWORD_CONSTEXPR_CPP14
that can be used to mark functions constexpr
when compiling with C++14 mode: BSLS_KEYWORD_CONSTEXPR_CPP14 int complexConstexprFunc(bool b) { if (b) { return 42; // RETURN } else { return 17; // RETURN } }
constexpr
support it is possible to use the result of complexConstexprFunc
in compile-time constants: void useComplexConstexprFunc() { #ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR_CPP14 constexpr #endif int result = complexConstexprFunc(true); ASSERT(42 == result);
BSLS_KEYWORD_CONSTEXPR_CPP14
can also be used on variables to achieve an identical result: BSLS_KEYWORD_CONSTEXPR_CPP14 int result2 = complexConstexprFunc(true); ASSERT(42 == result2); }
constexpr
function. Notably, a lambda can now be defined in such a function (and, if not called at compile time, does not itself need to be constexpr
). To take advantage of this there is a separate macro BSLS_KEYWORD_CONSTEXPR_CPP17
that can be used to mark functions constexpr
when compiling with C++17 mode: BSLS_KEYWORD_CONSTEXPR_CPP17 int moreComplexConstexprFunc(bool b) { if (b) { return 42; // RETURN } else { #if BSLS_COMPILERFEATURES_CPLUSPLUS >= 201103L return []{ static int b = 17; return b; }(); // RETURN #else return 17; #endif } }
useComplexConstexprFunc
, we can invoke moreComplexConstexprFunc
to populate a compile-time constant when it is supported: void useMoreComplexConstexprFunc() { BSLS_KEYWORD_CONSTEXPR_CPP17 int result = moreComplexConstexprFunc(true); ASSERT(42 == result); }