52 votes

std :: ignore pour ignorer la variable non utilisée

Est-ce une bonne approche d’utiliser std::ignore pour ignorer les variables non utilisées?

Supposons que j'ai une fonction comme celle-ci:

 void func(int i)
{
   //for some reason, I don't need i anymore but I cannot change signature of function    
   std::ignore = i; 
}
 

Information additionnelle

C’était un exemple et certaines réponses suggéraient d’utiliser des variables anonymes . Mais comment pourrais-je le faire pour d'autres cas, comme:

 int Thread_UnSafe_func_returnSomething():
void func()
{
   // To make it thread safe
   // Also it is required to call only once
   static int i = Thread_UnSafe_func_returnSomething();

   std::ignore = i;
}
 

60voto

Hayt Points 110

std::ignore peuvent travailler, mais il est destiné à être utilisé pour des n-uplets. Si vous avez besoin d'inclure le tuple en-tête et qui sait ce que les opérations sont effectuées à la cession. Cela peut également briser dans une autre version c++ parce qu'il n'a jamais été documentée pour être utilisé de cette façon.

Une meilleure façon pour cela est le C++17 attribut [[maybe_unused]]

void func([[maybe_unused]] int i)
{
}

Elle place la déclaration du droit à la déclaration de la variable, de sorte que vous n'avez pas à les déclarer dans une ligne supplémentaire ou de la déclaration.

La même chose peut être utilisé pour les locaux (local et statique) variables

...
[[maybe_unused]] static int a = something();
...

Et aussi pour beaucoup d'autres:

Apparaît dans la déclaration d'une classe, d'une définition de type, une variable, un non membre de données, une fonction, une énumération ou un agent recenseur. Si le compilateur émet des avertissements inutilisés entités, cet avertissement est supprimée pour toute entité déclarée maybe_unused.

Voir http://en.cppreference.com/w/cpp/language/attributes

Comme pour les personnes concernées que vous pouvez toujours utiliser les variables d'après vous les déclarez inutilisés:

Oui, c'est possible, mais (au moins avec clang), vous obtiendrez des mises en garde dans le cas où vous utilisez maybe_unused les variables déclarées.

50voto

Alexey Guseynov Points 3838

Dans ce cas, il suffit de ne pas écrire nom de la variable:

void func(int /*i*/)
{
    ...
}

@Hayt la réponse est bonne, mais utilise la dernière version de C++ qui n'est pas toujours disponible. Ne pas écrire le nom de variable est un vieux de la convention à dire un compilateur que vous n'avez pas besoin de la variable.

Pour une mise à jour de question que je voudrais aller pour une instance statique d'une classe ayant besoin d'initialisation dans le constructeur. Je dis initialisation parce que la seule raison pour laquelle je peux faire pour avoir une telle fonction est d'initialiser certains objet global.

class SomethingInitializer {
public:
    SomethingInitializer() {
        func_returnSomething();
    }
    ~SomethingInitializer() {
        // Note, that when you initialize something it is a good practice to deinitialize it at the end, and here is a proper place for that.
    }
};

void func() {
    static SomethingInitializer initializer;
}

Cette solution a un petit bonus: SomethingInitializer est RAII conforme. Ainsi, lorsque l'application se termine destructeur est appelé, et il peut faire deinitialization.

Remarque, que le compilateur sait que les classes peuvent faire quelque chose d'utile dans le constructeur et le destructeur, donc il ne va pas se plaindre non utilisés variable.

16voto

gsamaras Points 9567

std::ignorer n'était pas destiné à être utilisé à cette fin:

Un objet de type non spécifié, tel que n'importe quelle valeur peut être affectée à elle sans effet. Conçu pour une utilisation avec std::cravate lors de la décompression d'un std::tuple, comme un espace réservé pour les arguments qui ne sont pas utilisés.


Je vous suggère de ne pas faire ce que vous pensez, car dans le monde réel big projet, il va conduire à un code qui est plus difficile à maintenir, d'où l'on regarde le prototype d'une fonction, serait de voir qu'il prend un argument int i, mais la fonction ne serait pas nécessaire que, dans la réalité, de ne pas se sentir bien, n'est ce pas? :)

12voto

Jarod42 Points 15729

Comme alternative, sans supprimer i de la signature (certains outils de documentation le nécessitant éventuellement), il existe plusieurs façons de faire taire l'avertissement:

 void func(int i)
{
   static_cast<void>(i); // Silent warning for unused variable
}
 

Ce n’est pas totalement portable, mais c’est la mise en garde sur la plupart des compilateurs.

La manière propre est de créer une fonction dédiée pour cela:

 template <typename T>
void Unused(T&& /*No name*/) { /*Empty*/ }
 

puis

 void func(int i)
{
   Unused(i); // Silent warning for unused variable
}
 

2voto

Jacob Manaker Points 185

Je pense que vous avez un problème XY ici. Vous ne vous souciez pas vraiment de savoir comment ignorer les variables statiques; vous souhaitez simplement appeler une fonction une fois (et une seule fois) de manière réentrante, en toute sécurité.

À ce que je dis: avez-vous entendu parler de std::call_once ? Vous devriez réécrire votre méthode en tant que

 #include <mutex>

int Thread_UnSafe_func_returnSomething();
void func(void)
{
      //To make it thread safe
     static std::once_flag initComplete;
     std::call_once(initComplete, func_returnSomething);
 }
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X