URL:     https://linuxfr.org/users/serge_ss_paille/journaux/un-peu-de-fun-c-esque
Title:   Un peu de fun C++esque
Authors: serge_sans_paille
Date:    2026-10-12T07:58:19+02:00
License: CC By-SA
Tags:    c++ et python
Score:   7


Demat'iNal,

En Python, les arguments d'une fonction sont évalués de gauche à droite. Le code suivant :

```python
def dump(i):
    print(i)

def foo(x, y):
    ...

foo(dump(0), dump(1))
```

Affichera ainsi un ``0`` suivi d'un ``1``.

En C++ (comme en C), nous n'avons pas de telle garantie, si bien que l'affichage est non spécifié : cela peut aussi bien être ``0`` suivi de ``1`` que ``1`` suivi de ``0`` pour :

```c++
int dump(int i) { std::cout << i << std::endl; }
void foo(int,int) {}

foo(dump(0), dump(1))
```

Mais avec la petite astuce suivante on peut forcer l'ordre d’exécution, car les arguments d'une ``initializer_list`` sont ordonnés (cf. https://timsong-cpp.github.io/cppwp/n3337/dcl.init.list#4) (ici en utilisant les *deduction guide*).

```c++
std::apply(foo, std::tuple{0, 1});
```

Cependant on force alors tous les arguments de `foo` à être passés par valeur. On peut améliorer ce comportement pour respecter les *r-value* etc de la façon suivante :

```c++
template<class... Ts>
class pack_args {
    std::tuple<Ts...> args;
    public:
    pack_args(Ts... args) : args{std::forward<Ts>(args)...} {}
    std::tuple<Ts...> get() && {
        return std::move(args);}
};

template<class... Ts>
pack_args(Ts&&...) -> pack_args<Ts...>;
```

Puis

```c++
std::apply(foo, pack_args{0, 1}.get());
```

Comme l'illustre ce lien godbolt : https://godbolt.org/z/dTejr9336

On a ainsi ordonné les arguments d'appel sans perdre le contrôle fin du passage d'argument que permet C++.

Et voilà, une petite sucrerie de C++, probablement rien de nouveau sous le soleil pour les experts, mais ça m'a beaucoup amusé de jouer avec ça hier soir !

Et accessoirement, ça résout un bug dans [Pythran](https://github.com/serge-sans-paille/pythran/), mais ça, c'est juste pour mon plaisir personnel. 
