2 votes

Expressions de pliage et pack de paramètres : différence entre Args&& et Args à l'intérieur de static_assert

Ce code provient de
https://en.cppreference.com/w/cpp/language/fold

template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args){
    static_assert((std::is_constructible_v<T, Args&&> && ...));
    (v.push_back(std::forward<Args>(args)), ...);
}

Je ne comprends pas pourquoi l'assert statique vérifie la présence de Args&& et non pour Args ?

1voto

bartop Points 3747

Ceci est fait pour des cas particuliers comme celui-ci, lorsque vous n'avez qu'une déclaration de type mais pas de définition ( std::is_constructible sur les types incomplets - Dans ce cas is_constructible est UB ) :

struct B;

struct A {
    A(const A&) = default;
    A(const B&) {}

    A(A&&) = default;
    A() = default;
};
B&& getB();

template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args){
    static_assert((std::is_constructible_v<T, Args&&> && ...));
    (v.push_back(std::forward<Args>(args)), ...);
}

template<typename T, typename... Args>
void push_back_vec2(std::vector<T>& v, Args&&... args){
    static_assert((std::is_constructible_v<T, Args> && ...));
    (v.push_back(std::forward<Args>(args)), ...);
}

int main(int argc, char* argv[])
{
    std::vector<A> a;

    push_back_vec(a, A(), A());
    push_back_vec2(a, A(), A());

    A aa;
    push_back_vec(a, aa, aa, A());
    push_back_vec2(a, aa, aa, A());

    push_back_vec(a, getB());
    // code below won't compile
    //push_back_vec2(a, aa, A(), getB());
}

Exemple concret

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