Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Opracował: baziorek
Język C++

remove_reference_t

[alias] Szablon aliasu pozyskujący z typu T typ, który nie jest referencją do l-wartości, ani referencją do r-wartości

Składnia

C/C++
#include <type_traits>
namespace std
{
    template < typename T >
    struct remove_reference;
   
    template < typename T >
    using remove_reference_t = typename remove_reference < T >::type;
}

Parametry szablonu

ParametrOpis
Tjest to typ z którego chcemy otrzymać typ nie będący ani lewą-referencją ani prawą-referencją

Opis szczegółowy

Jest to szablon aliasu, który z danego typu, będącego parametrem szablonu aliasu, zwraca tenże typ, nie będący ani lewą-referencją, ani prawą-referencją.

Dodatkowe informacje

Usuwanie referencji z typu odbywa się w trakcie kompilacji.

Rzucane wyjątki

Wszystko odbywa się w trakcie kompilacji, dlatego nie ma tutaj żadnych wyjątków.

Wymagania

Kompilator zgodny z C++14, lub posiadający implementację
std::remove_reference_t <>
.

Implementacja

C/C++
namespace std
{
    template < typename T >
    struct remove_reference
    {
        typedef T type;
    };
    template < typename T >
    struct remove_reference < T &>
    {
        typedef T type;
    };
    template < typename T >
    struct remove_reference < T &&>
    {
        typedef T type;
    };
   
    template < typename T >
    using remove_reference_t = typename remove_reference < T >::type;
}

Przykład

C/C++
#include <iostream>
#include <type_traits> // is_same
#include <iomanip>     // setw()
using namespace std;

template < typename T1, typename T2 >
void compareTypes( const char * types )
{
    cout << setw( 35 ) << types << " are the same: " << is_same < T1, T2 >() << endl;
}

int main()
{
    compareTypes < int, int >( "int, int" );
    compareTypes < int, int &>( "int, int&" );
    compareTypes < int, int &&>( "int, int&&" );
    compareTypes < int, const int &>( "int, const int&" );
   
    compareTypes < int, remove_reference_t < int >>( "int, remove_reference_t<int>" );
    compareTypes < int, remove_reference_t < int &>>( "int, remove_reference_t<int&>" );
    compareTypes < int, remove_reference_t < int &&>>( "int, remove_reference_t<int&&>" );
    compareTypes < int, remove_reference_t < const int &>>( "int, remove_reference_t<const int&>" );
}
Standardowe wyjście programu:
                           int, int are the same: 1
                          int, int& are the same: 0
                         int, int&& are the same: 0
                    int, const int& are the same: 0
       int, remove_reference_t<int> are the same: 1
      int, remove_reference_t<int&> are the same: 1
     int, remove_reference_t<int&&> are the same: 1
int, remove_reference_t<const int&> are the same: 0

Przykład zaawansowany - używający techniki Tag Dispatch

Przykład zaimspirowany z książki Scotta Meyersa "Skuteczny nowoczesny C++" sposób 27
C/C++
#include <iostream>
#include <type_traits> // is_same, true_type, false_type, is_integral, remove_reference_t
#include <set>
#include <string> // to_string()
using namespace std;

template < typename Dictionary, typename T >
void addToDictionary( Dictionary & dictionary, T && entry );

int main()
{
    set < string > dictionary;
   
    addToDictionary( dictionary, "Ala ma kota" );
    addToDictionary( dictionary, - 4 );
    addToDictionary( dictionary, "Ala ma psa" s );
    //addToDictionary(dictionary, 3.1415); // compile error
   
    cout << "\nDictionary contains:\n";
    for( const auto & entry: dictionary )
         cout << entry << '\n';
   
}


template < typename Dictionary, typename T >
void addToDictionaryImpl( Dictionary & dictionary, T && entry, std::false_type )
{
    static_assert( std::is_constructible < typename Dictionary::value_type, T >::value, "Not constructible!" );
    dictionary.emplace( std::forward < T >( entry ) );
}

template < typename Dictionary, typename T >
void addToDictionaryImpl( Dictionary & dictionary, T && entry, std::true_type )
{
    dictionary.emplace( std::to_string( entry ) );
}

template < typename Dictionary, typename T >
void addToDictionary( Dictionary & dictionary, T && entry )
{
    std::cout << "Adding to dictionary: " << entry << std::endl;
    using NoReferenceT = std::remove_reference_t < T >;
    addToDictionaryImpl( dictionary, std::forward < T >( entry ), std::is_integral < NoReferenceT >() );
}
Standardowe wyjście programu:
Adding to dictionary: Ala ma kota
Adding to dictionary: -4
Adding to dictionary: Ala ma psa

Dictionary contains:
-4
Ala ma kota
Ala ma psa

Linki zewnętrzne

Linki zewnętrzne