Składnia
#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
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
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
#include <iostream>
#include <type_traits>
#include <iomanip>
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
#include <iostream>
#include <type_traits>
#include <set>
#include <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 );
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