Namensräume
Varianten
Aktionen

std::is_convertible, std::is_nothrow_convertible

Von cppreference.com
< cpp‎ | types
 
 
Metaprogrammierungsbibliothek
Typmerkmale
Typkategorien
(C++11)
(C++11)(DR*)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11) 
(C++11)
(C++11)
Typeneigenschaften
(C++11)
(C++11)
(C++14)
(C++11)(deprecated in C++26)
(C++11)(bis C++20*)
(C++11)(veraltet in C++20)
(C++11)
Typmerkmalskonstanten
Metafunktionen
(C++17)
Unterstützte Operationen
Beziehungen und Eigenschaftsabfragen
Typmodifikationen
(C++11)(C++11)(C++11)
Typentransformationen
(C++11)(veraltet in C++23)
(C++11)(veraltet in C++23)
(C++11)
(C++11)(bis C++20*)(C++17)

(C++11)
(C++11)
(C++17)
Rationale Arithmetik zur Compilezeit
Ganzzahlsequenzen zur Compilezeit
 
Definiert in der Kopfdatei <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 (d. h. entweder std::declval<From>() mittels impliziter Konversionen in To konvertierbar ist, oder sowohl From als auch To cv-qualifizierte void sind), liefert sie das Mitgliedskonstante value mit dem Wert true. Andernfalls ist value gleich false. Für diesen Test wird die Verwendung von std::declval in der Return-Anweisung nicht als ODR-Verwendung betrachtet.

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

(seit C++26)
Zugriffsprüfungen werden so durchgeführt, als kämen sie aus einem Kontext, der von keinem der beiden Typen unabhängig ist. Nur die Gültigkeit des unmittelbaren Kontexts des Ausdrucks in der Return-Anweisung (einschließlich der Konvertierungen zum Rückgabetyp) wird berücksichtigt.
2) Analog zu (1), aber die Konvertierung ist auch noexcept.

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

Wenn eine Instanziierung einer Vorlage davon 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 eine der auf dieser Seite beschriebenen Vorlagen hinzufügt, ist das Verhalten undefiniert.

Inhalt

[bearbeiten] Hilfs-Variablentemplate

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)

Abgeleitet von std::integral_constant

Member-Konstanten

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

Memberfunktionen

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

Membertypen

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

[bearbeiten] 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 {};

[bearbeiten] Hinweise

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

Derzeit hat der Standard nicht festgelegt, ob die Zerstörung des durch die Konvertierung erzeugten Objekts (entweder eines Ergebnisobjekts oder eines an eine Referenz gebundenen Temporärs) 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

[bearbeiten] 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*>);
    // Note that the Perfect Forwarding constructor makes the class E be
    // "convertible" from everything. So, A is replaceable by 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"

[bearbeiten] Siehe auch

prüft, ob ein Typ eine Basisklasse des anderen Typs ist
(Klassenvorlage) [bearbeiten]
prüft, ob ein Typ eine Zeiger-interkonvertierbare (initiale) Basisklasse eines anderen Typs ist
(Klassenvorlage) [bearbeiten]
prüft, ob Objekte eines Typs zeigerinterkonvertierbar mit dem angegebenen Unterobjekt dieses Typs sind
(Funktionsvorlage) [bearbeiten]
gibt an, dass ein Typ implizit in einen anderen Typ konvertierbar ist
(Konzept) [bearbeiten]