Namespaces
Variants

std:: is_convertible, std:: is_nothrow_convertible

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

Compile-time rational arithmetic
Compile-time integer sequences
Definiert in Header <type_traits>
template < class From, class To >
struct is_convertible ;
(1) (seit C++11)
template < class From, class To >
struct is_nothrow_convertible ;
(2) (seit C++20)
1) Wenn die imaginäre Funktionsdefinition To test ( ) { return std:: declval < From > ( ) ; } wohlgeformt ist (das heißt, entweder std:: declval < From > ( ) mit impliziten Konvertierungen zu To konvertiert werden kann, oder sowohl From als auch To möglicherweise CV-qualifizierte void sind), dann liefert die Member-Konstante value den Wert true . Andernfalls ist value false . Für diese Überprüfung gilt die Verwendung von std::declval in der return-Anweisung nicht als ODR-use .

Wenn To ein Referenztyp ist und bei der Bindung von std:: declval < From > ( ) an To ein temporäres Objekt erzeugt würde, wird die return -Anweisung in der imaginären Funktion als wohlgeformt betrachtet, auch wenn eine solche Bindung in einer tatsächlichen Funktion nicht wohlgeformt wäre.

(seit C++26)
Zugriffsprüfungen werden durchgeführt, als ob sie aus einem Kontext stammten, der mit keinem der beiden Typen in Beziehung steht. Nur die Gültigkeit des unmittelbaren Kontexts des Ausdrucks in der return-Anweisung (einschließlich Konvertierungen in den Rückgabetyp) wird berücksichtigt.
2) Gleich wie (1) , aber die Konvertierung ist ebenfalls noexcept .

Wenn From oder To kein vollständiger Typ ist, (möglicherweise cv-qualifiziert) void , oder ein Array unbekannter Größe, ist das Verhalten undefiniert.

Wenn eine Instanziierung einer Vorlage oben direkt oder indirekt von einem unvollständigen Typ abhängt und diese Instanziierung ein anderes Ergebnis liefern könnte, wenn dieser Typ hypothetisch vervollständigt würde, ist das Verhalten undefiniert.

Wenn das Programm Spezialisierungen für irgendwelche der auf dieser Seite beschriebenen Templates hinzufügt, ist das Verhalten undefiniert.

Inhaltsverzeichnis

Hilfsvariablen-Template

template < class From, class To >
constexpr bool is_convertible_v = is_convertible < From, To > :: value ;
(seit C++17)
template < class From, class To >
constexpr bool is_nothrow_convertible_v = is_nothrow_convertible < From, To > :: value ;
(seit C++20)

Geerbt von std:: integral_constant

Member-Konstanten

value
[static]
true falls From zu To konvertierbar ist, false andernfalls
(öffentliche statische Member-Konstante)

Member-Funktionen

operator bool
konvertiert das Objekt zu bool , gibt value zurück
(öffentliche Member-Funktion)
operator()
(C++14)
gibt value zurück
(öffentliche Member-Funktion)

Member-Typen

Typ Definition
value_type bool
type std:: integral_constant < bool , value >

Mögliche Implementierung

is_convertible (1)
namespace detail
{
    template<class T>
    auto test_returnable(int) -> decltype(
        void(static_cast<T(*)()>(nullptr)), std::true_type{}
    );
    template<class>
    auto test_returnable(...) -> std::false_type;
    template<class From, class To>
    auto test_implicitly_convertible(int) -> decltype(
        void(std::declval<void(&)(To)>()(std::declval<From>())), std::true_type{}
    );
    template<class, class>
    auto test_implicitly_convertible(...) -> std::false_type;
} // namespace detail
template<class From, class To>
struct is_convertible : std::integral_constant<bool,
    (decltype(detail::test_returnable<To>(0))::value &&
     decltype(detail::test_implicitly_convertible<From, To>(0))::value) ||
    (std::is_void<From>::value && std::is_void<To>::value)
> {};
is_nothrow_convertible (2)
template<class From, class To>
struct is_nothrow_convertible : std::conjunction<std::is_void<From>, std::is_void<To>> {};
template<class From, class To>
    requires
        requires
        {
            static_cast<To(*)()>(nullptr);
            { std::declval<void(&)(To) noexcept>()(std::declval<From>()) } noexcept;
        }
struct is_nothrow_convertible<From, To> : std::true_type {};

Hinweise

Liefert wohldefinierte Ergebnisse für Referenztypen, void-Typen, Arraytypen und Funktionstypen.

Derzeit hat der Standard nicht festgelegt, ob die Zerstörung des durch die Konvertierung erzeugten Objekts (entweder ein Ergebnisobjekt oder ein temporäres Objekt, das an eine Referenz gebunden ist) als Teil der Konvertierung betrachtet wird. Dies ist LWG issue 3400 .

Alle bekannten Implementierungen behandeln die Zerstörung als Teil der Konvertierung, wie in P0758R1 vorgeschlagen.

Feature-Test Makro Wert Std Feature
__cpp_lib_is_nothrow_convertible 201806L (C++20) std::is_nothrow_convertible

Beispiel

#include <iomanip>
#include <iostream>
#include <string>
#include <string_view>
#include <type_traits>
class E { public: template<class T> E(T&&) {} };
int main()
{
    class A {};
    class B : public A {};
    class C {};
    class D { public: operator C() { return c; } C c; };
    static_assert(std::is_convertible_v<B*, A*>);
    static_assert(!std::is_convertible_v<A*, B*>);
    static_assert(std::is_convertible_v<D, C>);
    static_assert(!std::is_convertible_v<B*, C*>);
    // Beachten Sie, dass der Perfect Forwarding-Konstruktor die Klasse E
    // "konvertierbar" von allem macht. Daher ist A ersetzbar durch B, C, D..:
    static_assert(std::is_convertible_v<A, E>);
    static_assert(!std::is_convertible_v<std::string_view, std::string>);
    static_assert(std::is_convertible_v<std::string, std::string_view>);
    auto stringify = []<typename T>(T x)
    {
        if constexpr (std::is_convertible_v<T, std::string> or
                      std::is_convertible_v<T, std::string_view>)
            return x;
        else
            return std::to_string(x);
    };
    using std::operator "" s, std::operator "" sv;
    const char* three = "three";
    std::cout << std::quoted(stringify("one"s)) << ' '
              << std::quoted(stringify("two"sv)) << ' '
              << std::quoted(stringify(three)) << ' '
              << std::quoted(stringify(42)) << ' '
              << std::quoted(stringify(42.0)) << '\n';
}

Ausgabe:

"one" "two" "three" "42" "42.000000"

Siehe auch

(C++11)
prüft, ob ein Typ eine Basis eines anderen Typs ist
(Klassen-Template)
prüft, ob ein Typ eine pointer-interconvertible (anfängliche) Basis eines anderen Typs ist
(Klassen-Template)
prüft, ob Objekte eines Typs pointer-interconvertible mit dem spezifizierten Subobjekt dieses Typs sind
(Funktions-Template)
spezifiziert, dass ein Typ implizit in einen anderen Typ konvertierbar ist
(Konzept)