IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

std::make_array pour c++14 ?


Sujet :

C++

  1. #21
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    C'est possible un array de lambda ? (ça devrait, mais impossible de compiler chez moi, ni sur VS2012, ni sur gcc 4.8.0)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template<typename T, typename ... Args>
    auto make_array(T t, Args ... args) -> std::array<T, sizeof...(Args)+1> {
    	return std::array<T, sizeof...(Args)+1>({{t, args...}});
    }
     
    int main() {
    	auto f = [](int i)->int { return i; };
    	auto f2 = [](int i)->int { return i*2; };
     
    	std::array<decltype(f), 2> arr = {{ f, f2 }};
    	auto arr2 = make_array(f, f2);
     
    	return 0;
    }
    Mais au moins l'erreur est originale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    #include<array>
    #include<functional>
     
     
    template<typename T, typename ... Args>
    auto make_array(T t, Args ... args) -> std::array< std::function<int(int)>, sizeof...(Args)+1> {
       return {{t, args...}};
    }
     
    int main() {
    	auto f = [](int i)->int { return i; };
    	auto f2 = [](int i)->int { return i*2; };
     
    	auto arr2 = make_array(f, f2);
     
    	return 0;
    }
    bon certes valable uniquement pour ce type précis de lambda....

  2. #22
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    C'est possible un array de lambda ? (ça devrait, mais impossible de compiler chez moi, ni sur VS2012, ni sur gcc 4.8.0)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template<typename T, typename ... Args>
    auto make_array(T t, Args ... args) -> std::array<T, sizeof...(Args)+1> {
    	return std::array<T, sizeof...(Args)+1>({{t, args...}});
    }
     
    int main() {
    	auto f = [](int i)->int { return i; };
    	auto f2 = [](int i)->int { return i*2; };
     
    	std::array<decltype(f), 2> arr = {{ f, f2 }};
    	auto arr2 = make_array(f, f2);
     
    	return 0;
    }
    Mais au moins l'erreur est originale
    Mince.

    Ca vient peut-être du fait que chaque lambda pourrait bien avoir un type unique. Du coup, decltype(f2) != decltype(f) ; mais la norme C++ dit que les messages d'erreur doivent être le plus simple possible - du coup, le compilateur transforme le type réel en un nom de type lisible (et il apparait identique, vu que la signature des lambda est identique).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #23
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    Mince.

    Ca vient peut-être du fait que chaque lambda pourrait bien avoir un type unique. Du coup, decltype(f2) != decltype(f) ; mais la norme C++ dit que les messages d'erreur doivent être le plus simple possible - du coup, le compilateur transforme le type réel en un nom de type lisible (et il apparait identique, vu que la signature des lambda est identique).
    http://liveworkspace.org/code/2jJoBz$33

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    source.cpp: In instantiation of 'std::array<T, (sizeof (Args ...) + 1)> make_array(T, Args ...) [with T = main()::__lambda0; Args = {main()::__lambda1}]':

    T = main()::__lambda0
    Args = {main()::__lambda1}


    ===> type unique


    make_array générique:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include<array>
    #include<functional>
     
     
    template<typename U, typename T, typename ... Args>
    auto make_array(U u, T t, Args ... args) -> std::array< decltype(u), sizeof...(Args)+1> {
       return {{t, args...}};
    }
     
    int main() {
       auto f = [](int i)->int { return i; };
    	auto f2 = [](int i)->int { return i*2; };
     
    	auto arr2 = make_array(std::function<int(int)>(), f,  f2);
     
    	return 0;
    }

  4. #24
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par guillaume07 Voir le message
    http://liveworkspace.org/code/2jJoBz$33

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    source.cpp: In instantiation of 'std::array<T, (sizeof (Args ...) + 1)> make_array(T, Args ...) [with T = main()::__lambda0; Args = {main()::__lambda1}]':

    T = main()::__lambda0
    Args = {main()::__lambda1}


    ===> type unique
    Plus exactement, le standard dit (parce que, restons honnètes, même si ça temps à s'améliorer les compilateurs font souvent un peu ce qu'ils veulent au niveau du respect du standard)

    Citation Envoyé par c++11 section 5.1.2§3
    The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type — called the closure type — whose properties are described below. This class type is not an aggregate (8.5.1). The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression. [ Note: This determines the set of namespaces and classes associated with the closure type (3.4.2). The parameter types of a lambda-declarator do not affect these associated namespaces and classes. — end note ] An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:
    • the size and/or alignment of the closure type,
    • whether the closure type is trivially copyable (Clause 9),
    • whether the closure type is a standard-layout class (Clause 9), or
    • whether the closure type is a POD class (Clause 9).
    An implementation shall not add members of rvalue reference type to the closure type.
    Donc, effectivement, un array de lambda, c'est impossible a créer.

    Par contre, sans ce cas particulier, une implémentation de make_array() pourrait renvoyer un array d'objets fonctions polymorphiques - quelque chose qui, selon moi, devrait figurer dans un proposal digne de ce nom.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  5. #25
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Donc, effectivement, un array de lambda, c'est impossible a créer.
    <Mode chipotage="On">
    C'est possible, à condition que toutes les lambdas soient du même type, et que l'array reste vide
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <array>
     
    using namespace std;
     
    int main()
    {
    	auto l = [](int i){return 2*i;};
    	typedef decltype(l) Lambda;
    	array<Lambda, 42> myArray;
    }
    </Mode>
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #26
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    un array de std::function ça marche donc si on peut infiné

  7. #27
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    Citation Envoyé par guillaume07 Voir le message
    make_array générique:
    Tu peux aussi utiliser le code que j'ai posté sur la page précédente pour faire la même chose, en spécifiant explicitement le type T lors de l'appel à la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <array>
    #include <functional>
     
    template<typename T, typename ... Args>
    auto make_array(T t, Args ... args) -> std::array<T, sizeof...(Args)+1> {
        return std::array<T, sizeof...(Args)+1>({{t, args...}});
    }
     
    int main() {
        auto f = [](int i)->int { return i; };
        auto f2 = [](int i)->int { return i*2; };
     
        auto arr2 = make_array<std::function<int(int)>>(f, f2);
     
        return 0;
    }

  8. #28
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Par défaut
    Citation Envoyé par Kalith Voir le message
    Tu peux aussi utiliser le code que j'ai posté sur la page précédente pour faire la même chose, en spécifiant explicitement le type T lors de l'appel à la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <array>
    #include <functional>
     
    template<typename T, typename ... Args>
    auto make_array(T t, Args ... args) -> std::array<T, sizeof...(Args)+1> {
        return std::array<T, sizeof...(Args)+1>({{t, args...}});
    }
     
    int main() {
        auto f = [](int i)->int { return i; };
        auto f2 = [](int i)->int { return i*2; };
     
        auto arr2 = make_array<std::function<int(int)>>(f, f2);
     
        return 0;
    }
    je pensais pas qu'on pouvait que partiellement spécifier le type des paramètres templates au moment de l'appel

    solution sans préciser le paramètre template:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    #include <array>
    #include <functional>
     
    template<typename T> struct remove_class { };
    template<typename C, typename R, typename... A>
    struct remove_class<R(C::*)(A...) const>{using type = R(A...);};
     
    template<typename F> using make_function_type = 
    std::function<typename remove_class<decltype(&std::remove_reference<F>::type::operator())>::type>;
     
    template<typename T, typename ... Args>
    auto make_array(T&& t, Args&& ... args) -> std::array<make_function_type<T>, sizeof...(Args)+1>
    {
        return {{std::forward<T>(t), std::forward<Args>(args)...}};
    }
     
    int main()
    { 
       auto f = [](int i)->int { return i; };
       auto f1 = [](int i)->int { return i; };
     
        make_array (f,f1);
     
       return 1;
    }

  9. #29
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Citation Envoyé par guillaume07 Voir le message
    je pensais pas qu'on pouvait que partiellement spécifier le type des paramètres templates au moment de l'appel
    Tant que le compilateur est capable de déduite ceux que tu ne précices pas (dans l'ordre donc) il n'y a pas de problème. Pour faire simple : il est en général inutile de préciser l'ensemble des paramètres template qui sont utilisés dans les types des paramètres de la fonction.

  10. #30
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Boost Assignment ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vector<int> v;
    v += 1,2,3,4,5,6,7,8,9;

Discussions similaires

  1. Utilisation de std::function pour créer un bouton
    Par Invité dans le forum SL & STL
    Réponses: 19
    Dernier message: 28/09/2014, 17h12
  2. std::allocator pour char et wchar_t
    Par Meseira dans le forum SL & STL
    Réponses: 6
    Dernier message: 24/04/2013, 14h20
  3. Problème avec std::stringstream pour lire un fichier OBJ
    Par Kromagg dans le forum Développement 2D, 3D et Jeux
    Réponses: 3
    Dernier message: 01/12/2010, 18h49
  4. prédicat pour min_element d'une std::map
    Par Kurisu dans le forum SL & STL
    Réponses: 6
    Dernier message: 11/09/2006, 19h27
  5. [débutant] equivalent à sprintf pour les std::string
    Par Biosox dans le forum SL & STL
    Réponses: 22
    Dernier message: 26/08/2005, 12h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo