J'ai le code suivant utilisant des concepts:

struct bar {
    void foo() {}
};

template <typename T>
concept Fooable = requires (const T& t) { // const bar& t doesn't support t.foo()
    { t.foo() };
};

template <typename Fooable>
void callfoo(Fooable bar)
{
    bar.foo();
}

int main()
{
    bar b;
    callfoo(b);

    return 0;
}

Je m'attendrais à ce que le code ne soit pas compilé car bar ne prend pas en charge l'appel de foo() sur une instance const. Cependant, il compile bien - lien.

La description de la liste des paramètres sur cppreference n'est pas très utile à cet égard :

liste de paramètres - une liste de paramètres séparés par des virgules comme dans une déclaration de fonction, sauf que les arguments par défaut ne sont pas autorisés et qu'il ne peut pas se terminer par des points de suspension (autre que celui signifiant une extension de pack). Ces paramètres n'ont pas de stockage, de liaison ou de durée de vie et ne sont utilisés que pour aider à spécifier les exigences. Ces paramètres sont dans la portée jusqu'à la fermeture } de l'exigence-seq.

Est-ce que je comprends mal à quoi servent les qualificatifs cv dans une liste de paramètres d'expression requise ? Est-ce que je rate complètement quelque chose ? Je suis encore plus confus par cppreference ayant quelques exemples utilisant des paramètres de référence universels, il doit donc y avoir un sens.

J'utilise gcc9 avec -fconcepts (bien que gcc trunk et clang avec des concepts sur godbolt conviennent également à ce code, alors ne supposez pas que c'est lié au compilateur).

1
Stephan Dollberg 23 févr. 2020 à 23:52

1 réponse

Meilleure réponse

Vous avez un bug dans votre fonction callfoo. Vous utilisez un nom de type, pas un concept. Remplacez la déclaration par

template <Fooable Foo>
void callfoo(Foo bar)

Ou

void callfoo(Fooable auto bar)
6
Timo 23 févr. 2020 à 21:21