2017-06-24 4 views
7

Je veux vérifier si un type a une entrée dans std :: numeric_limits. Lorsque le type est un tableau - (ou peut-être pas un nombre?), J'obtiens une erreur de compilation. Cela m'empêche de détecter et de ramifier selon que le type est supporté dans std :: numeric_limits. J'apprécierais n'importe quel aperçu que quelqu'un veut partager.Détection de la spécialisation de std :: numeric :: type <T> pour un type non numérique 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

Pouvez-vous donner un exemple de exactement comment/où vous voulez "détecter et branchez"? Je devine quelque chose dans un modèle, plutôt que pour un type fixe comme 'char [20]', dont nous connaissons tous la réponse? – aschepler

+1

Définir "détecter et ramifier". Le but de 'static_assert' est, en effet, d'émettre une erreur de compilation si l'assertion échoue. Si vous avez besoin d'un résultat différent, vous devez expliquer ce que c'est. –

Répondre

2

Cela se produit parce que si vous jetez un oeil à l'intérieur std::numeric_limits ou jetez un oeil à la documentation que vous verrez les déclarations des méthodes comme le

suivant
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; 

Ici comme vous pouvez le voir, il y a des fonctions qui renvoient T en valeur et C++ ne supporte pas les types de tableaux de retour en valeur (voir Why doesn't C++ support functions returning arrays?)

Ainsi, la ligne suivante ne compilera pas

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

Et toute nouvelle tentative de vérifier directement si is_specialized œuvres pour un type ne seront pas directement avec SFINAE compilent parce qu'il y aura une erreur produite (en raison du retour des types de tableaux comme expliqué ci-dessus) qui ne sont pas dans le contexte immédiat de le gabarit. Donc, vous devez examiner le concept qui est pris en charge pour std::numeric_limits (dans ce cas std::is_arithmetic)

Cependant tout ce que vous devez faire ici pour faire ce travail est de std::decay_t le type

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

Et maintenant, il sera travaillez parce que vous avez explicitement décomposé le type de tableau en pointeur et que cela peut être renvoyé par la fonction. Vous avez probablement voulu faire cela en premier lieu parce que vous ne voulez pas appeler accidentellement std::numeric_limits::is_specialized pour un type non-décomposé comme