7
votes

Classe de référence littérale à chaîne

in C ++ 1y , puis-je avoir une classe de référence qui se lie à une chaîne littérale mais non à char * ou char [] & ou similaire? XXX


13 commentaires

Le mieux que je puisse arriver est de fournir une surcharge de matrice Static_assert ou utilisez le mot-clé explicite.


@Borglaireur Mais je ne pense pas qu'il existe un moyen de distinguer un littéral à chaîne et une matrice Cons-Char.


@BorGlaader Comment allez-vous static_assert que quelque chose est un littéral à chaîne? Et comment explicite aide ici? En réalité, si vous pouvez static_assert que quelque chose est un littéral à chaîne, vous pouvez également utiliser le même état avec SFIAE pour contrôler la résolution de la surcharge pour ne pas se lier à la fonction en premier lieu.


@Borglaireur s'il vous plaît partagez-la.


Je suppose que le mieux que vous puissiez faire est d'utiliser const char (& s) [n] (avec modèle ) comme type de paramètre. Mais il se lie également à n'importe quel réseau de Cons-Char, autre qu'un littéral à chaîne.


@Holyblackcat C'est une sorte de , comme je l'ai dit "Le meilleur que je puisse arriver" avec "ou j'aurais dû dire le plus proche. Je ne pense pas que les besoins / besoins opés sont nécessaires à 100%.


Code de démonstration pour mon dernier commentaire: ideone.com/d9olzv


@Borglaireur Aucun de vos appels de test n'est appelé avec un littéral à chaîne. Ils utilisent tous les deux des variables, pas des littéraux. Je comprends la question qui est exactement ce qui devrait être probihited ...


@Leemes Votre solution se lie également aux tableaux de caractères non-Const.


Je sais. Vous ne pouvez pas changer cela. La constance peut toujours être ajoutée, mais non supprimée. Vous ne pouvez ajouter qu'une surcharge non constituée, mais = Supprimer IT.


Avez-vous vraiment voulu dire sizeof (s) ? Parce que c'est 1 dans votre cas ... Vous vouliez probablement dire strallen (s) ou Tailleof (s) - 1 si s est un tableau. Ou Tailleof (s) même dans ce cas? Notez la terminaison zéro, qui est incluse dans la taille de la matrice, mais pas dans la taille de la chaîne (SHLEN).


@LEEMES TIMILOF est généralement de 4 (arches 32 bits, char_bit == 8) ou 8 (64 bits arcs) pour un pointeur ou la taille de stockage (y compris la terminaison 0) pour un littéral ou une matrice. Je voulais dire mon taille _ pour stocker la taille de stockage (exactement comme dans votre réponse), mais soustraire ou non soustrait 1 de la taille supporte peu de pertinence à la question. ;-)


Ouais, je voulais dire 4 bien sûr;)


3 Réponses :


1
votes
class LitRf{
  const char* data_;
  Sz size_;
public:
  LitRf(const char* /*?*/ s) : data_{s},size_{sizeof(s)} { /*?*/ }
  LitRf(char*) = delete;
};

0 commentaires

3
votes

C ++ 11 retiré le seul moyen formel de détecter un littéral à chaîne en tant que tel, à savoir via sa conversion implicite au pointeur vers le non-const.

Quoi qu'il en soit à l'aide du petit tour, il fallait utiliser la macro.

en C ++ 11 et plus tard, le mieux que vous puissiez faire est d'établir une convention solide que un tableau de Const est un littéral.

IE, avec votre exemple, xxx

Notez l'utilisation de Taille_t au lieu d'un type éventuellement signé SZ . Cela garantit que le code compilera avec g ++. Malheureusement, ce compilateur, ou des versions plus anciennes de celui-ci, a un bug où il est tout à fait insistant sur Taille_t , sinon il refuse d'accepter le code.


5 commentaires

Merci. Char Cons [] ~ String Literal est un compromis raisonnable. Malheureusement, cela initialisera également à partir d'un tableau de caractères non constitué. (Peu importe le sz . Je ne savais pas que c'était quelque chose - je l'utilise comme un Typedef pour std :: taille_t dans mon Espace de noms)


Mais vous ne pouvez pas différencier un tableau de Const Char et a const de char


Pourquoi Tailleofof (S) - 1 ? Je sais, la résiliation 0, mais OP ne soustrait pas cela à l'origine.


Ah, oubliez-le - je suppose que l'op ne veut pas faire sizeof (s) parce que c'est 1 dans son cas - il signifiait probablement strylen qui correspondrait bien à votre code.


Ajout d'un constructeur inaccessible et supprimé pour empêcher la construction d'une matrice de non- const char .



3
votes

Je suppose que le meilleur que vous puissiez faire est d'utiliser const char (& s) [n] code> (avec modèle code>) comme type de paramètre. Mais il se lie également à tout gamme de Cons-charme autre qu'un littéral à chaîne.

Ajoutez un constructeur de tableau de caractères non supprimé pour interdire l'appelant avec un tableau non-Const. P>

class LitRf
{
    const char* data_;
    Sz size_;
public:
    // Called by the macro MakeLitRf. Unlikely to be called directly unless the user knows what he's doing.
    LitRf(const char *s, void *)
        : data_{s}, size_{N}
    {}

    // Called without macro! Throw a compiler error, explaining what's wrong.
    LitRf(const char *s)
    {
        static_assert(false, "Please use the macro `MakeLitRf` with a string literal to construct a `LitRf`.");
    }
};

#define MakeLitRf(s) LitRf(s "", nullptr)


0 commentaires