117 votes

Quelle est la signification de l'expression "... ..." ? Par exemple, l'opérateur de double ellipse sur le paquet de paramètres.

En parcourant l'implémentation actuelle de gcc des nouveaux en-têtes C++11, je suis tombé sur le jeton "......". Vous pouvez vérifier, que le code suivant compile bien [via ideone.com].

template <typename T>
struct X
{ /* ... */ };

template <typename T, typename ... U>
struct X<T(U......)> // this line is the important one
{ /* ... */ };

Alors, quelle est la signification de ce jeton ?

edit : On dirait que SO a coupé "......" dans le titre de la question en "...", je voulais vraiment dire "......" . :)

81voto

Potatoswatter Points 70305

Chaque cas de cette bizarrerie est associé à un cas d'ellipse simple normale.

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes...)>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes......)>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
    { typedef _Res result_type; };

Je pense que la double ellipse a un sens similaire à celui de _ArgTypes..., ... c'est-à-dire une expansion de modèle variadique suivie d'une liste de varargs de style C.

Voici un test soutenant cette théorie Je pense que nous avons un nouveau gagnant pour le pire pseudo-opérateur de tous les temps.

Editar: Cela semble être conforme. Le §8.3.5/3 décrit une façon de former la liste des paramètres comme suit

liste de déclaration des paramètres opt ... opt

La double ellipse est donc formée par une liste de déclarations de paramètres se terminant par un paquet de paramètres, suivie d'une autre ellipse.

La virgule est purement facultative ; le §8.3.5/4 dit en effet

Lorsque la syntaxe est correcte et que " ... " ne fait pas partie d'un déclarateur abstrait, " , ... " est synonyme de " ... ".

Ce site es au sein d'un déclarateur abstrait, [modifier] mais Johannes a raison de dire qu'ils font référence à un déclarateur abstrait dans une déclaration de paramètres. Je me demande pourquoi ils n'ont pas dit "partie d'une déclaration de paramètres", et pourquoi cette phrase n'est pas simplement une note informative

En outre, va_begin() en <cstdarg> nécessite un paramètre avant la liste de varargs, donc le prototype f(...) spécifiquement autorisé par le C++ est inutile. Si l'on se réfère à C99, c'est illégal en C. C'est donc très bizarre.

Note d'utilisation

Sur demande, voici une démonstration de la double ellipse :

#include <cstdio>
#include <string>

template< typename T >
T const &printf_helper( T const &x )
    { return x; }

char const *printf_helper( std::string const &x )
    { return x.c_str(); }

template< typename ... Req, typename ... Given >
int wrap_printf( int (*fn)( Req... ... ), Given ... args ) {
    return fn( printf_helper( args ) ... );
}

int main() {
    wrap_printf( &std::printf, "Hello %s\n", std::string( "world!" ) );
    wrap_printf( &std::fprintf, stderr, std::string( "Error %d" ), 5 );
}

-4voto

James Thompson Points 15464

C'est la définition d'un modèle variadique . Cela permet aux méthodes modélisées de prendre un nombre variable d'arguments.

Voici un exemple de Douglas Gregor qui définit une fonction printf sûre :

void printf(const char* s) {
  while (*s) {
    if (*s == '%' && *++s != '%') 
      throw std::runtime_error("invalid format string: missing arguments");
    std::cout << *s++;
  }
}

template<typename T, typename... Args>
void printf(const char* s, const T& value, const Args&... args) {
  while (*s) {
    if (*s == '%' && *++s != '%') {
      std::cout << value;
      return printf(++s, args...);
    }
    std::cout << *s++;
  }
  throw std::runtime_error("extra arguments provided to printf");
}

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