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 :

Étendre un foncteur générique simple


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Étendre un foncteur générique simple
    Bonjour à tous (ça fait un bail que je passais plus par ici )

    Voici un petit code sympa de foncteur générique simple.
    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
    template<class C, typename T, T C::*P>
    struct by_member
    {
    	bool operator()(C const & rl, C const & rr) const
    	{
    		return rl.*P < rr.*P;
    	}
    	bool operator()(C const & rl, T const & t) const
    	{
    		return rl.*P < t;
    	}
    	bool operator()(T const & t, C const & rr) const
    	{
    		return t < rr.*P;
    	}
    };
    Et voici un petit code exemple d'utilisation (je vous laisse ajouter les #include nécessaires si vous l'essayer).
    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
    struct employee
    {
    	int         f_id;
    	std::string f_firstname;
    	std::string f_lastname;
    	int         f_ssnumber;
     
    	employee(int id, std::string const & firstname, std::string const & lastname, int ssnumber) :
    		f_id(id), f_firstname(firstname), f_lastname(lastname), f_ssnumber(ssnumber) {}
    };
     
    typedef by_member<employee, std::string, &employee::f_lastname> by_lastname;
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	std::vector<employee> v;
    	v.push_back(employee(5, "John", "Smith", 1582));
    	v.push_back(employee(3, "Paul", "Howard", 1777));
    	v.push_back(employee(7, "Jude", "Muller", 1325));
    	std::sort(v.begin(), v.end(), by_lastname());
    	if ( std::binary_search(v.begin(), v.end(), "Muller", by_lastname()) )
    		std::cout << "Found" << std::endl;
    	return 0;
    }
    Simple, propre et efficace me semble-t-il.


    Maintenant je souhaiterais un foncteur utilisant deux membres de employee (ou plus) afin de former une clé multiple permettant de trier puis rechercher sur, par exemple, f_lastname et f_firstname.

    Je pensais adapter by_member<> comme ceci (c'est juste un début de réflexion):
    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
    template<class C, typename T1, T1 C::*P1, typename T2, T2 C::*P2>
    struct by_2_members
    {
    	bool operator()(C const & rl, C const & rr) const
    	{
    		return rl.*P1 < rr.*P1 || (rl.*P1 == rr.*P1 && rl.*P2 < rr.*P2);
    	}
    	bool operator()(C const & rl, Tuple? const & t) const
    	{ // ici ça coince...
    		return rl.*P1 < t<1> || (rl.*P1 == t<1> && rl.*P2 < t<2>);
    	}
    	bool operator()(Tuple? const & t, C const & rr) const
    	{ // et ici aussi...
    		return t<1> < rr.*P1 || (t<1> == rr.*P1 && t<2> < rr.*P2);
    	}
    };
    Pour un usage comme ceci par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef by_2_members<employee, std::string, &employee::f_lastname, std::string, &employee::f_firstname> by_lastname_firstname;
     
    	...
     
    	std::sort(v.begin(), v.end(), by_lastname_firstname());
    	if ( std::binary_search(v.begin(), v.end(), std::tuple("Muller", "Jude"), by_lastname_firstname()) )
    		std::cout << "Found" << std::endl;
    Je n'aime que moyennement utiliser std::tuple<>, toute idée pour l'éviter est bienvenue.

    Ensuite l'usage d'un variadic template pour écrire une forme générale de by_member<> serait pas mal aussi (sans tout transformer en usine à gaz).

    Merci pour vos avis

  2. #2
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Bonjour

    J'aime bien l'utilisation de std::tuple, j'ai essayé de le remplacer (dans les signatures) par std::initializer_list mais j'ai pas réussi à donner un brace-enclosed initializer list à std::binary_search (j'ai pas trop chercher).

    Voila le code avec std::tuple. Je te laisse le soin de rajouter la généricité voulue.
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    // g++ -Wall -Wextra -Wconversion -Wsign-conversion -Ofast -std=c++11 -pedantic -fopenmp main.cpp -o main && ./main
     
    #include <iostream>
    #include <array>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <tuple>
     
    struct employee
    {
    	int         f_id;
    	std::string f_firstname;
    	std::string f_lastname;
    	int         f_ssnumber;
     
    	employee(int id, std::string const & firstname, std::string const & lastname, int ssnumber) :
    		f_id(id), f_firstname(firstname), f_lastname(lastname), f_ssnumber(ssnumber)
    	{ }
    };
     
    struct comp
    {
    	bool operator()(employee const & a, employee const & b)
    	{
    		return std::tie(a.f_lastname, a.f_firstname) < std::tie(b.f_lastname, b.f_firstname);
    	}
     
    	// std::tuple
     
    // 	bool operator()(employee const & e, std::tuple<std::string, std::string> const & value)
    // 	{
    // 		return std::tie(e.f_lastname, e.f_firstname) < value;
    // 	}
    // 	
    // 	bool operator()(std::tuple<std::string, std::string> const & value, employee const & e)
    // 	{
    // 		return value < std::tie(e.f_lastname, e.f_firstname);
    // 	}
     
    	// std::tuple template
     
    	template <class value_t>
    	bool operator()(employee const & e, value_t const & value)
    	{
    		return std::tie(e.f_lastname, e.f_firstname) < value;
    	}
     
    	template <class value_t>
    	bool operator()(value_t const & value, employee const & e)
    	{
    		return value < std::tie(e.f_lastname, e.f_firstname);
    	}
     
    	// std::initializer_list
     
    // 	bool operator()(employee const & e, std::initializer_list<std::string> const & value)
    // 	{
    // 		return std::tie(e.f_lastname, e.f_firstname) < std::tie(value.begin()[0], value.begin()[1]);
    // 	}
    // 	
    // 	bool operator()(std::initializer_list<std::string> const & value, employee const & e)
    // 	{
    // 		return std::tie(value.begin()[0], value.begin()[1]) < std::tie(e.f_lastname, e.f_firstname);
    // 	}
    };
     
    int main()
    {
    	std::vector<employee> v;
     
    	v.push_back(employee(5, "John", "Smith", 1582));
    	v.push_back(employee(3, "Paul", "Howard", 1777));
    	v.push_back(employee(4, "Jane", "Howard", 1847));
    	v.push_back(employee(7, "Jude", "Muller", 1325));
     
    	for (auto const & e : v) { std::cout << e.f_lastname << " " << e.f_firstname << std::endl; }
    	std::cout << std::endl;
     
     
    	std::sort(v.begin(), v.end(), comp());
     
    	for (auto const & e : v) { std::cout << e.f_lastname << " " << e.f_firstname << std::endl; }
    	std::cout << std::endl;
     
     
    	if (std::binary_search(v.begin(), v.end(), std::make_tuple("Muller", "Jude"), comp()))
    // 	if (std::binary_search(v.begin(), v.end(), std::initializer_list<std::string>{ "Muller", "Jude" }, comp()))
    	{
    		std::cout << "Found" << std::endl;
    	}
     
    	return 0;
    }

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Et bien merci !
    Je n'ai jamais utiliser les tuple<> encore, c'est l'occasion de commencer.
    Ça n'a pas l'air mal du tout, mais j'ignore si l'usage des fonctions std::tie(), std::forward_as_tuple(), std::make_tuple(), etc, est pénalisant en performance.

    Voici le foncteur version 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
    template<class C,
    	typename T1, T1 C::*P1,
    	typename T2, T2 C::*P2>
    struct by_member2
    {
    	bool operator()(C const & rl, C const & rr) const
    	{
    		return std::tie(rl.*P1, rl.*P2) < std::tie(rr.*P1, rr.*P2);
    	}
    	bool operator()(C const & rl, std::tuple<T1, T2> && t) const
    	{
    		return std::tie(rl.*P1, rl.*P2) < t;
    	}
    	bool operator()(std::tuple<T1, T2> && t, C const & rr) const
    	{
    		return t < std::tie(rr.*P1, rr.*P2);
    	}
    };
    Et un peu de code pour illustrer l'usage:
    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
    typedef by_member<employee, std::string, &employee::f_lastname> by_lastname;
    typedef by_member2<employee,
    	std::string, &employee::f_lastname,
    	std::string, &employee::f_firstname> by_lastname_firstname;
     
    ...
     
    	std::vector<employee> v;
    	v.push_back(employee(5, "John", "Smith", 1582));
    	v.push_back(employee(3, "Paul", "Howard", 1777));
    	v.push_back(employee(4, "Jane", "Howard", 1847));
    	v.push_back(employee(7, "Jude", "Muller", 1325));
    	std::sort(v.begin(), v.end(), by_lastname_firstname());
    	if ( std::binary_search(v.begin(), v.end(), "Muller", by_lastname()) )
    		std::cout << "Found 1" << std::endl;
    	if (std::binary_search(v.begin(), v.end(), std::forward_as_tuple("Muller", "Jude"), by_lastname_firstname()))
    		std::cout << "Found 2" << std::endl;
    	if (!std::binary_search(v.begin(), v.end(), std::forward_as_tuple("Howard", "John"), by_lastname_firstname()))
    		std::cout << "Not Found 2" << std::endl;
    Je souhaiterai maintenant généraliser le foncteur pour un tri/recherche sur N membres.
    Mais là je ne vois pas trop comment m'y prendre.
    Une aide serait bienvenue. Merci !

  4. #4
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Pour les performances :
    Le temps de compilation est plus long (dans la version générique donnée en dessous, dès que j'ajoute le foncteur à 3 éléments, le temps de compilation passe de 3,5 secondes à 4,3).
    Le temps d'exécution est normalement le même que la version écrite à la main à partir de l'optimisation -O1. En effet, les std::tuple n'apparaissent plus dans le code assembleur (tu peux vérifier sur https://gcc.godbolt.org/)

    Voici le brouillon du code générique. J'ai utilisé C++14 mais à part le auto en retour de fonction, le code devrait fonctionner en C++11. J'ai utilisé des lambdas car à la base je voulais directement les passer en paramètre template à la structure mais je ne sais pas si ce genre de code est possible en C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Déclaration
    template <class ... T, T ...>
    struct type;
    // Utilisation
    type<5, 3.14, "char *"> t;
    Si oui, je te laisse changer ça si besoin.
    Cela permettrai de ne pas stocker les fonctions dans le std::tuple qui nous empêche d'utiliser ... directement (je dois passer par seq<S ...>).

    Je n'ai pas nettoyé le code il doit avoir moyen de le simplifier, ne serait-ce qu'en séparant les différentes parties indépendantes et en donnant des noms plus explicites.
    Je prend mes paramètres par T const &, ça peut être une limitation a enlevée en rendant le code (encore) plus générique.
    Au final le code est relativement court (et haut niveau (et complexe)).
    L'utilisation est sympathique comme souvent en C++
    Voilà le code :
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    // g++ -Wall -Wextra -Wconversion -Wsign-conversion -Ofast -std=c++14 -pedantic -fopenmp main.cpp -o main && ./main
     
    #include <iostream>
    #include <array>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <tuple>
     
     
     
    template<int ...>
    struct seq { };
     
    template<int N, int ...S>
    struct gens : gens<N-1, N-1, S...> { };
     
    template<int ...S>
    struct gens<0, S...> {
      typedef seq<S...> type;
    };
     
     
    struct employee
    {
    	int         f_id;
    	std::string f_firstname;
    	std::string f_lastname;
    	int         f_ssnumber;
     
    	employee(int id, std::string const & firstname, std::string const & lastname, int ssnumber) :
    		f_id(id), f_firstname(firstname), f_lastname(lastname), f_ssnumber(ssnumber)
    	{ }
    };
     
    std::ostream & operator <<(std::ostream & out, employee const & e)
    {
    	out << "{ " << e.f_id << ", " << e.f_firstname << ", " << e.f_lastname << ", " << e.f_ssnumber << " }";
    	return out;
    }
     
     
    template <class T, class ... getter_t>
    struct comp_generic
    {
    private:
     
    	std::tuple<getter_t const ...> m_getters;
     
    public:
     
    	comp_generic(getter_t const & ... getters) : m_getters(std::make_tuple(getters...))
    	{ }
     
    	// operator()(T const & a, T const & b)
     
    	bool operator()(T const & a, T const & b)
    	{
    		return fct_T_T(a, b, typename gens<sizeof...(getter_t)>::type());
    	}
     
    	template <int ... S>
    	bool fct_T_T(T const & a, T const & b, seq<S ...> const)
    	{
    		return std::tie(std::get<S>(m_getters)(a)...) < std::tie(std::get<S>(m_getters)(b)...);
    	}
     
    	// operator()(T const & t, values_t const & values)
     
    	template <class values_t>
    	bool operator()(T const & t, values_t const & values)
    	{
    		return fct_T_values(t, values, typename gens<sizeof...(getter_t)>::type());
    	}
     
    	template <class values_t, int ... S>
    	bool fct_T_values(T const & t, values_t const & values, seq<S ...> const)
    	{
    		return std::tie(std::get<S>(m_getters)(t)...) < values;
    	}
     
    	// operator()(values_t const & values, T const & t)
     
    	template <class values_t>
    	bool operator()(values_t const & values, T const & t)
    	{
    		return fct_values_T(values, t, typename gens<sizeof...(getter_t)>::type());
    	}
     
    	template <class values_t, int ... S>
    	bool fct_values_T(values_t const & values, T const & t, seq<S ...> const)
    	{
    		return values < std::tie(std::get<S>(m_getters)(t)...);
    	}
    };
     
    template <class T, class ... getter_t>
    auto make_comp(getter_t const & ... getters)
    {
    	return comp_generic<T, getter_t const & ...>(getters...);
    }
     
    int main()
    {
    	std::vector<employee> v;
     
    	v.push_back(employee(5, "John", "Smithh", 1582));
    	v.push_back(employee(3, "Paul", "Howard", 1777));
    	v.push_back(employee(1, "Paul", "Howard", 1798));
    	v.push_back(employee(4, "Jane", "Howard", 1847));
    	v.push_back(employee(7, "Jude", "Muller", 1325));
     
    	for (auto const & e : v) { std::cout << e << std::endl; } std::cout << std::endl;
     
    	auto const get_id = [](employee const & e) -> int const & { return e.f_id; };
    	auto const get_firstname = [](employee const & e) -> std::string const &  { return e.f_firstname; };
    	auto const get_lastname = [](employee const & e) -> std::string const & { return e.f_lastname; };
    	auto const get_ssnumber = [](employee const & e) -> int const & { return e.f_ssnumber; };
     
    	auto const comp_ssnumber = make_comp<employee>(get_ssnumber);
    	auto const comp_firstname = make_comp<employee>(get_firstname);
    	auto const comp_id = make_comp<employee>(get_id);
    	auto const comp_lastname_firstname = make_comp<employee>(get_lastname, get_firstname);
    	auto const comp_lastname_firstname_id = make_comp<employee>(get_lastname, get_firstname, get_id);
     
     
    	std::cout << "Sort by id" << std::endl;
     
    	std::sort(v.begin(), v.end(), comp_id);
     
    	if (std::binary_search(v.begin(), v.end(), std::make_tuple(5), comp_id))
    	{
    		std::cout << "{ 5, _, _, _ } found in:" << std::endl;
    	}
     
    	for (auto const & e : v) { std::cout << e << std::endl; } std::cout << std::endl;
     
     
    	std::cout << "Sort by firstname" << std::endl;
     
    	std::sort(v.begin(), v.end(), comp_firstname);
     
    	for (auto const & e : v) { std::cout << e << std::endl; } std::cout << std::endl;
     
     
    	std::cout << "Sort by lastname and firstname" << std::endl;
     
    	std::sort(v.begin(), v.end(), comp_lastname_firstname);
     
    	for (auto const & e : v) { std::cout << e << std::endl; } std::cout << std::endl;
     
     
    	std::cout << "Sort by ssnumber" << std::endl;
     
    	std::sort(v.begin(), v.end(), comp_ssnumber);
     
    	for (auto const & e : v) { std::cout << e << std::endl; } std::cout << std::endl;
     
     
    	std::cout << "Sort by lastname and firstname and id" << std::endl;
     
    	std::sort(v.begin(), v.end(), comp_lastname_firstname_id);
     
    	if (std::binary_search(v.begin(), v.end(), std::make_tuple("Howard", "Jane", 4), comp_lastname_firstname_id))
    	{
    		std::cout << "{ 4, Howard, Jane, _ }" << "found:" << std::endl;
    	}
     
    	for (auto const & e : v) { std::cout << e << std::endl; } std::cout << std::endl;
     
    	return 0;
    }

  5. #5
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Et bien merci encore
    J'en apprends des choses.

    J'ai modifié ton code en supprimant les seq<> et gens<> puisque cela existe déjà (std::index_sequence<> et std::index_sequence_for<>)
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    template <class T, class ... getter_t>
    struct comp_generic
    {
    private:
     
    	std::tuple<getter_t const ...> m_getters;
     
    public:
     
    	comp_generic(getter_t const & ... getters) : m_getters(std::make_tuple(getters...))
    	{ }
     
    	// operator()(T const & a, T const & b)
     
    	bool operator()(T const & a, T const & b)
    	{
    		return fct_T_T(a, b, std::index_sequence_for<getter_t...>{});
    	}
     
    	template <std::size_t ... S>
    	bool fct_T_T(T const & a, T const & b, std::index_sequence<S ...> const)
    	{
    		return std::tie(std::get<S>(m_getters)(a)...) < std::tie(std::get<S>(m_getters)(b)...);
    	}
     
    	// operator()(T const & t, values_t const & values)
     
    	template <class values_t>
    	bool operator()(T const & t, values_t const & values)
    	{
    		return fct_T_values(t, values, std::index_sequence_for<getter_t...>{});
    	}
     
    	template <class values_t, std::size_t ... S>
    	bool fct_T_values(T const & t, values_t const & values, std::index_sequence<S ...> const)
    	{
    		return std::tie(std::get<S>(m_getters)(t)...) < values;
    	}
     
    	// operator()(values_t const & values, T const & t)
     
    	template <class values_t>
    	bool operator()(values_t const & values, T const & t)
    	{
    		return fct_values_T(values, t, std::index_sequence_for<getter_t...>{});
    	}
     
    	template <class values_t, std::size_t ... S>
    	bool fct_values_T(values_t const & values, T const & t, std::index_sequence<S ...> const)
    	{
    		return values < std::tie(std::get<S>(m_getters)(t)...);
    	}
    };
    Ça compile et tourne tel quel sous VS2015, et le résultat est comme attendu.

    Mais comme tu le soulignes, le mieux serait de passer sous forme de paramètres le(s) membre(s) de structure directement à comp_generic<> comme je l'ai fait dans mes essais de code (structure by_member).
    L'usage de lambda ne me semble pas élégant dans ce cas-ci (et c'est du fonctionnel).

    C'est plus lisible d'écrire quelque chose comme by_member<employee, std::string, &employee::f_firstname> plutot
    que [](employee const & e) -> std::string const & { return e.f_firstname; }.
    Enfin, il me semble.

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    Citation Envoyé par camboui Voir le message
    C'est plus lisible d'écrire quelque chose comme by_member<employee, std::string, &employee::f_firstname> plutot
    que [](employee const & e) -> std::string const & { return e.f_firstname; }.
    Enfin, il me semble.
    std::mem_fn(&employee::f_firstname), enfin, il me semble

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 29/01/2015, 00h51
  2. Liste Simple Générique
    Par amateurc dans le forum C++
    Réponses: 8
    Dernier message: 29/09/2009, 20h33
  3. Générateur de forumlaire simple ou éditeur générique
    Par jean2ce dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 06/11/2006, 23h47
  4. Edition d'un simple fichier java
    Par mcrepin dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 21/03/2003, 14h28
  5. recherche exemple simple pour corba en c++
    Par Pinggui dans le forum CORBA
    Réponses: 4
    Dernier message: 06/05/2002, 11h29

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