[PYTHON] Indépendant du type à l'aide de modèles C ++

introduction

Lorsque je recherchais comment utiliser la bibliothèque C ++ avec un peu de connaissances en C, des modèles apparaissaient souvent. À ce moment-là, je n'ai pas bien compris le modèle et je l'ai ignoré, mais quand je l'ai vérifié à nouveau, c'était assez utile, j'ai donc résumé le contenu recherché avec un échantillon simple et des exemples qui peuvent être utilisés.

environnement

modèle

Description du modèle

Quand j'ai recherché le modèle, j'étais confus par le modèle de nom. Oubliez la signification du modèle Word et lisez-le. Un modèle est simplement une fonction (ou une classe) indépendante du type. En C ++, il est normal de spécifier des types pour les variables et les valeurs de retour, mais il est inutile et impossible de créer des fonctions (ou classes) adaptées à tous les types, donc des fonctions (ou classes) qui reçoivent tous les types avec une fonction appelée template ) Peut être créé.

Format du modèle

Exemple d'application aux arguments

L'application d'un modèle est facile. Ajoutez simplement `` template '' au-dessus de la fonction (ou classe), et le type du nom de variable spécifié dans cette fonction (ou classe) changera pour le type spécifié par l'appelant. Faire. Vous pouvez l'appeler comme une fonction normale.

cppMain.cpp


template <typename Nom de l'argument>
nom de la fonction void(Nom de l'argument){
Traitement dans la fonction
}

//Comment appeler
int main(){
    int a = 1;
Nom de la fonction(a);
Nom de la fonction<int>(a);
}

Exemple d'application à la valeur de retour

Lors de l'application du type de retour, ajoutez simplement template <nom de la variable typename> '' au-dessus de la fonction (ou de la classe). Une chose dont il faut faire attention ici est le type à renvoyer avec return```. Étant donné que le type retourné par return doit être le même que le type de retour défini, le return value name '' dans l'exemple ci-dessous doit être retourné.

cppMain.cpp


template <typename Nom de retour>
Nom de la valeur de retour Nom de la fonction(){
Renvoyer le nom a=valeur;
Traitement dans la fonction
    return a;
}

Un exemple simple de modèle

Dans cet exemple, nous créons une fonction avec un argument T qui peut accepter n'importe quel type. Le contenu de la fonction affiche uniquement le type de la variable T dans la sortie standard. Lorsque le type int est donné à la fonction, le type std :: string est donné et le résultat lorsque le pointeur est donné est affiché.

cppMain.cpp


#include <typeinfo>
#include <iostream>
#include <cxxabi.h>

template <typename T>
static void print_type(T){
    int status;
    std::cout << "type name:" << abi::__cxa_demangle(typeid(T).name(), 0, 0, &status) << std::endl;
}

int main(){
    int a = 1;
    print_type(a);

    std::string b = "ab";
    print_type(b);

    char* e = "ab";
    print_type(e);
}

résultat

# ./cppMain
type name:int
type name:std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
type name:char*

En regardant les résultats, nous pouvons voir que nous pouvons passer tous les types standard tels que int, des classes telles que std :: string et des pointeurs. Cette fois, c'est une fonction qui ne sort qu'en standard, donc je ne connais pas son utilité, mais je vais présenter un exemple qui peut être utilisé dans l'exemple suivant.

Exemples de modèles utilisables

Comme exemple qui peut être réellement utilisé, prenez le convertisseur de Définition du convertisseur C ++ et python avec boost python. Dans l'exemple précédent, il s'agissait d'un convertisseur limité au type int, mais si vous appliquez un modèle, vous pouvez désormais convertir un autre type que int. J'ai également appliqué un modèle à la fonction `` get_list () '' qui récupère la liste afin qu'elle renvoie une valeur de retour différente même s'il s'agit de la même fonction. Cela rend inutile la création de convertisseurs pour tous les types, et s'il y a des fonctions qui peuvent être utilisées en commun, cela peut être géré en changeant simplement le port de divulgation en python.

Après application

cppMod.cpp


#include <boost/python.hpp>

#include <iostream>

template <typename T>
struct vec_to_list_convert {
    static PyObject* convert(std::vector<T> const& vec) {
        boost::python::list pyList;
        for (auto item: vec) {
            pyList.append(item);
        }
        return boost::python::incref(pyList.ptr());
    }
};


class Greeting {
    public:

    template <typename T>
    std::vector<T> get_list() {
        std::vector<T> cppVec;
        cppVec.push_back(1);
        cppVec.push_back(2);
        
        return cppVec;
    }
};


BOOST_PYTHON_MODULE(CppMod) {

    boost::python::to_python_converter<const std::vector<int>, vec_to_list_convert<int>>();
    boost::python::to_python_converter<const std::vector<double>, vec_to_list_convert<double>>();

    boost::python::class_<Greeting>("greeting")
    .def("get_int_list", &Greeting::get_list<int>)
    .def("get_double_list", &Greeting::get_list<double>);
}

résultat

# python3
>>> import CppMod
>>> a=CppMod.greeting()
>>> a.get_int_list()
[1, 2]
>>> a.get_double_list()
[1.0, 2.0]

en conclusion

J'ai mis en place un modèle. Bien qu'il soit suffisamment compétent pour se développer sans le savoir, il a été très utile pour étudier comment utiliser la bibliothèque et pour réaliser un développement efficace et propre tenant compte du code.

Recommended Posts

Indépendant du type à l'aide de modèles C ++
utilisation de golang slack édition C2
Outil de révision de code C utilisant pycparser
Créez un wrapper de langage C à l'aide de Boost.Python
Exécuter du code Python sur C ++ (en utilisant Boost.Python)
Utilisez libxlsxwriter pour exporter des fichiers xlsx en C ++.
Introduction à Tornado (3): Développement à l'aide de modèles [Pratique]