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

Langage C++ Discussion :

Appel d'une classe template ?


Sujet :

Langage C++

  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut Appel d'une classe template ?
    Hello,

    Par un jeu un peu étonnant, je suis arrivé à un code comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<typename T>
    class assert_type_not_copyable {
    	static_assert(not std::is_copy_constructible<T>(), "Error! Type should not be copy constructible");
    	static_assert(not std::is_copy_assignable<T>(), "Error! Type should not be copy assignable");
    };
    Ca fait bien le taff :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class OK {
    	OK(const OK&) = delete;
    	OK& operator=(const OK&) = delete;
    };
     
    int main() {
    	assert_type_not_copyable<OK>();
    }
    Mon interrogation vient du fait que je dois mettre les parenthèses lors de l'utilisation, comme ci on appelait la classe. Il se passe quoi en fait ?

    Merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Salut,

    la parenthèse instancier l'objet puis l'opérateur bool sera utilisé pour convertir en machin testable.
    Mais en général ces trucs se manipulent plutôt via leur membre static value.
    Le résultat est identique de toutes façons, c'est juste de la préférence d'écriture.

    http://www.cplusplus.com/reference/t...constructible/
    http://www.cplusplus.com/reference/t...%20value_type/
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 460
    Points : 6 064
    Points
    6 064
    Par défaut
    Salut,

    std::is_copy_constructible<T>() crée un objet de type std::is_copy_constructible<T> en appelant le constructeur par défaut. On aurait pu aussi l'écrire std::is_copy_constructible<T>{}.
    not est un synonyme de !, donc not std::is_copy_constructible<T>() signifie !std::is_copy_constructible<T>{}. Le compilateur fait une conversion en booléen en appelant la fonction membre operator bool de la classe std::is_copy_constructible<T>.

    Avant le C++17, on écrivait plutôt std::is_copy_constructible<T>::value. Depuis le C++17, on écrit plutôt std::is_copy_constructible_v<T>.

    Attention, si tu utilises un std::is_copy_constructible dans un static_assert en attendant les concepts du C++20, alors il y a peut-être un problème dans ton code. Les classes de <type_traits> sont insidieuses.

    Voici un bout de code qui illustre le problème :
    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
    #include <iostream>
    #include <string>
    #include <type_traits>
    #include <utility>
     
    template<class T>
    class Test1 {
    private:
    	T m_member;
    public:
    	template<class U>
    	Test1& operator=(U&& arg) {
    		static_assert(std::is_assignable_v<T&, U&&>);
    		m_member = std::forward<U>(arg);
    		return *this;
    	}
    };
     
    template<class T>
    class Test2 {
    private:
    	T m_member;
    public:
    	template<class U, std::enable_if_t<std::is_assignable_v<T&, U&&>, int> = 0>
    	Test2& operator=(U&& arg) {
    		m_member = std::forward<U>(arg);
    		return *this;
    	}
    };
     
    int main()
    {
    	std::cout
    		<< "std::is_assignable_v<Test1<int>&, std::string> : "
    		<< (std::is_assignable_v<Test1<int>&, std::string> ? "true" : "false") << ".\n"
    		<< "std::is_assignable_v<Test2<int>&, std::string> : "
    		<< (std::is_assignable_v<Test2<int>&, std::string> ? "true" : "false") << ".\n";
    	return 0;
    }
    La sortie est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::is_assignable_v<Test1<int>, std::string> : true.
    std::is_assignable_v<Test2<int>, std::string> : false.
    Si tu essaies d'affecter un std::string à un Test1<int>& ou à un Test2<int>&, tu auras une erreur de compilation.
    Et pourtant, std::is_assignable_v<Test1<int>&, std::string> retourne true.
    Par contre, std::is_assignable_v<Test2<int>&, std::string> retourne bien false.

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Pyramidev Voir le message
    std::is_copy_constructible<T>() crée un objet de type std::is_copy_constructible<T> en appelant le constructeur par défaut.
    Ça parait évident une fois dit comme ça...

    Merci pour vos réponses !

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 11/09/2012, 20h48
  2. Réponses: 4
    Dernier message: 22/11/2010, 15h15
  3. Réponses: 4
    Dernier message: 08/11/2005, 16h10
  4. Trouver le Type d'une classe template dynamiquement ?
    Par Serge Iovleff dans le forum Langage
    Réponses: 3
    Dernier message: 23/09/2005, 17h48
  5. [PL/SQL]Appel d'une classe/méthode java
    Par marsup54 dans le forum SQL
    Réponses: 4
    Dernier message: 30/06/2004, 17h44

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