2017-06-24 30 views
7

Chcę sprawdzić, czy typ ma wpis w std :: numeric_limits. Kiedy typ jest tablicą - (lub może nie liczbą?) Pojawia się błąd kompilatora. Zapobiega mi to wykrywanie i rozgałęzienia na podstawie tego, czy typ jest obsługiwany w std :: numeric_limits. Byłbym wdzięczny za każdy wgląd, który każdy chce udostępnić.Wykrywanie specjalizacji std :: numeric :: type <T> dla niektórych typów nieliczbowych T

// the following provokes compiler error on Clang 
// Function cannot return array type 'type' (aka 'char [20]') 
static_assert(
    ! std::numeric_limits<char[20]>::is_specialized, 
    "! std::numeric_limits<char[20]>::is_specialized" 
); 
// invokes static assert on compile as expected 
static_assert(
    std::numeric_limits<char[20]>::is_specialized, 
    "std::numeric_limits<char[20]>::is_specialized" 
); 
+1

Czy możesz podać przykład dokładnie, jak/gdzie chcesz "wykryć i rozgałęzić"? Zgaduję coś wewnątrz szablonu, zamiast stałego typu, takiego jak "char [20]", na który wszyscy znamy odpowiedź? – aschepler

+1

Zdefiniuj "wykrywanie i rozgałęzianie". Celem 'static_assert' jest w istocie wydanie błędu kompilacji, jeśli asercja się nie powiedzie. Jeśli potrzebujesz innego wyniku, musisz wyjaśnić, co to jest. –

Odpowiedz

2

Dzieje się tak dlatego, jeśli spojrzeć wewnątrz std::numeric_limits lub przyjrzeć się dokumentacji widać deklaracje metod jak na poniższym

template<class T> 
class numeric_limits 
{ 
public: 
    static constexpr bool is_specialized = false; 
    static constexpr T min() noexcept; 
    static constexpr T max() noexcept; 
    static constexpr T lowest() noexcept; 

Tutaj, jak widać nie są to funkcje, które zwracają T przez wartość, a C++ nie obsługuje powrocie typy tablicy przez wartość (patrz Why doesn't C++ support functions returning arrays?)

więc następujący wiersz nie zostanie skompilowany

std::numeric_limits<char[20]>::is_specialized 

I dalej próba bezpośrednio sprawdzić, czy is_specialized prace dla typu bezpośrednio z SFINAE nie skompilować, ponieważ nie będzie błąd produkowany (z powodu powrotu typów tablicowych jak wyjaśniono powyżej), że nie znajduje się w bezpośrednim kontekście szablon. Więc trzeba by sprawdzić koncepcję, która jest obsługiwana przez std::numeric_limits (w tym przypadku std::is_arithmetic)

Jednak wszystko, co trzeba zrobić, żeby zrobić to praca jest std::decay_t typu

std::numeric_limits<std::decay_t<char[20]>>::is_specialized 

A teraz to będzie działa, ponieważ jawnie rozpadł się typ tablicy na wskaźnik i jest zwracany z funkcji. Najprawdopodobniej chciałeś to zrobić, ponieważ nie chcesz przypadkowo zadzwonić pod numer std::numeric_limits::is_specialized dla typu nie zepsutego, takiego jak const int&