Provide a compile-time check for type conversion.
More...
Classes |
struct | bslmf::IsConvertible_CheckComplete< t_TYPE &, false > |
struct | bslmf::IsConvertible_CheckComplete< t_TYPE, true > |
struct | bslmf::IsConvertible_CheckComplete< t_TYPE[], false > |
struct | bslmf::IsConvertible_Match::no_type |
struct | bslmf::IsConvertible_Imp< t_FROM_TYPE, t_TO_TYPE > |
struct | bslmf::IsConvertible_LazyTrait< t_TO_TYPE > |
struct | bslmf::IsConvertible_IsNeverConvertible< t_FROM_TYPE, t_TO_TYPE > |
struct | bslmf::IsConvertible_FilterNeverConvertible< t_FROM_TYPE, t_TO_TYPE > |
struct | bslmf::IsConvertible_Conditional< t_FROM_TYPE, t_TO_TYPE > |
struct | bsl::is_convertible_dispatch< t_TYPE, t_TYPE & > |
struct | bsl::is_convertible_dispatch< t_TYPE, const t_TYPE & > |
struct | bsl::is_convertible_dispatch< t_TYPE, volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< t_TYPE, const volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< const t_TYPE, t_TYPE & > |
struct | bsl::is_convertible_dispatch< const t_TYPE, const t_TYPE & > |
struct | bsl::is_convertible_dispatch< const t_TYPE, volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< const t_TYPE, const volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE, t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE, const t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE, volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE, const volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< const volatile t_TYPE, t_TYPE & > |
struct | bsl::is_convertible_dispatch< const volatile t_TYPE, const t_TYPE & > |
struct | bsl::is_convertible_dispatch< const volatile t_TYPE, volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< const volatile t_TYPE, const volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< t_TYPE &, t_TYPE & > |
struct | bsl::is_convertible_dispatch< t_TYPE &, const t_TYPE & > |
struct | bsl::is_convertible_dispatch< t_TYPE &, volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< t_TYPE &, const volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< const t_TYPE &, t_TYPE & > |
struct | bsl::is_convertible_dispatch< const t_TYPE &, const t_TYPE & > |
struct | bsl::is_convertible_dispatch< const t_TYPE &, volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< const t_TYPE &, const volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE &, t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE &, const t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE &, volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE &, const volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< const volatile t_TYPE &, t_TYPE & > |
struct | bsl::is_convertible_dispatch< const volatile t_TYPE &, const t_TYPE & > |
struct | bsl::is_convertible_dispatch< const volatile t_TYPE &, volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< const volatile t_TYPE &, const volatile t_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_TYPE, t_TYPE > |
struct | bsl::is_convertible_dispatch< t_FROM_TYPE, volatile t_TO_TYPE & > |
struct | bsl::is_convertible_dispatch< t_FROM_TYPE, const volatile t_TO_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_FROM_TYPE &, volatile t_TO_TYPE & > |
struct | bsl::is_convertible_dispatch< volatile t_FROM_TYPE &, const volatile t_TO_TYPE & > |
struct | bsl::EffectiveFromType< t_FROM_TYPE > |
struct | bsl::is_convertible_dispatch< volatile t_FROM_TYPE &, t_TO_TYPE > |
struct | bsl::is_convertible< t_FROM_TYPE, t_TO_TYPE > |
Typedefs |
typedef bsl::integral_constant
< bool, value > | bslmf::IsConvertible_Imp::type |
Enumerations |
enum | { bslmf::IsConvertible_CheckComplete::k_CHECK_COMPLETE = sizeof(t_TYPE)
} |
enum | { bslmf::IsConvertible_Imp::value
} |
Functions |
static yes_type | bslmf::IsConvertible_Match::match (IsConvertible_Match &) |
template<class t_TYPE > |
static no_type | bslmf::IsConvertible_Match::match (const t_TYPE &) |
template<class t_TYPE > |
static no_type | bslmf::IsConvertible_Match::match (const volatile t_TYPE &) |
template<class t_TYPE > |
static bsl::enable_if
< bsl::is_function< t_TYPE >
::value, no_type >::type | bslmf::IsConvertible_Match::match (t_TYPE &) |
Detailed Description
- Outline
-
-
- Purpose:
- Provide a compile-time check for type conversion.
-
- Classes:
-
- See also:
- Component bslmf_integralconstant
-
- Description:
- This component defines two meta-functions,
bsl::is_convertible
and BloombergLP::bslmf::IsConvertible
and a template variable bsl::is_convertible_v
, that represents the result value of the bsl::is_convertible
meta-function. All these meta-functions may be used to check whether an implicit conversion exists from one type to another.
bsl::is_convertible
meets the requirements of the is_convertible
template defined in the C++11 standard [meta.rel], while bslmf::IsConvertible
was devised before is_convertible
was standardized.
- The two meta-functions are functionally equivalent except that
bsl::is_convertible
does not allow its template parameter types to be incomplete types according to the C++11 standard while bslmf::IsConvertible
tests conversions involving incomplete types. The other major difference between them is that the result for bsl::is_convertible
is indicated by the class members value
and type
, whereas the result for bslmf::IsConvertible
is indicated by the class members VALUE
and Type
.
- Note that
bsl::is_convertible
should be preferred over bslmf::IsConvertible
, and in general, should be used by new components. Also note that bsl::is_convertible
and bslmf::IsConvertible
can produce compiler errors if the conversion is ambiguous. For example: Also note that the template variable is_convertible_v
is defined in the C++17 standard as an inline variable. If the current compiler supports the inline variable C++17 compiler feature, bsl::is_convertible_v
is defined as an inline constexpr bool
variable. Otherwise, if the compiler supports the variable templates C++14 compiler feature, bsl::is_convertible_v
is defined as a non-inline constexpr bool
variable. See BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES
and BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
macros in bsls_compilerfeatures component for details.
-
- Usage:
- In this section we show intended use of this component.
-
- Example 1: Select Function Based on Type Convertibility:
- The
bsl::is_convertible
meta-function can be used to select an appropriate function (at compile time) based on the convertibility of one type to another without causing a compiler error by actually trying the conversion.
- First, we define two classes,
Foo
and Bar
. The Foo
class has an explict constructor from int
, an implicit conversion operator that returns an integer value while the Bar
class does neither: class Foo {
int d_value;
public:
explicit Foo(int value) : d_value(value) {}
operator int() const { return d_value; }
};
class Bar {};
Then, we run: Note that int
to Foo
is false, even though Foo
has a constructor that takes an int
. This is because that constructor is explicit, and is_converitble
ignores explicit constructors.
- Next, we go on to demonstrate how this could be used. Suppose we are implementing a
convertToInt
template method that converts a given object of the (template parameter) t_TYPE
to int
type, and returns the integer value. If the given object can not convert to int
, return 0. The method calls an overloaded function, getIntValue
, to get the converted integer value. The idea is to invoke one version of getIntValue
if the type provides a conversion operator that returns an integer value, and another version if the type does not provide such an operator.
- We define the first
getIntValue
function that takes a bsl::false_type
as its last argument, whereas the second getIntValue
function takes a bsl::true_type
object. The result of the bsl::is_convertible
meta-function (i.e., its type
member) is used to create the last argument passed to getIntValue
. Neither version of getIntValue
makes use of this argument -- it is used only to differentiate the argument list so we can overload the function. template <class t_TYPE>
inline
int getIntValue(t_TYPE *, bsl::false_type)
{
return 0;
}
template <class t_TYPE>
inline
int getIntValue(t_TYPE *object, bsl::true_type)
{
return int(*object);
}
Now, we define our convertToInt
method: template <class t_TYPE>
inline
int convertToInt(t_TYPE *object)
{
typedef typename bsl::is_convertible<t_TYPE,
int>::type CanConvertToInt;
return getIntValue(object, CanConvertToInt());
}
Notice that we use bsl::is_convertible
to get a bsl::false_type
or bsl::true_type
, and then call the corresponding overloaded getIntValue
method.
- Finally, we call our finished product and observe the return values:
Foo foo(99);
Bar bar;
assert(99 == convertToInt(&foo));
assert(0 == convertToInt(&bar));
Typedef Documentation
template<class t_FROM_TYPE , class t_TO_TYPE >
Enumeration Type Documentation
template<class t_TYPE, bool = bsl::is_function<t_TYPE>::value || bsl::is_void<t_TYPE>::value>
anonymous enum [inherited] |
template<class t_FROM_TYPE , class t_TO_TYPE >
anonymous enum [inherited] |
Function Documentation
static yes_type bslmf::IsConvertible_Match::match |
( |
IsConvertible_Match & |
|
) |
[static, inherited] |
template<class t_TYPE >
static no_type bslmf::IsConvertible_Match::match |
( |
const t_TYPE & |
|
) |
[static, inherited] |
template<class t_TYPE >
static no_type bslmf::IsConvertible_Match::match |
( |
const volatile t_TYPE & |
|
) |
[static, inherited] |