Puis-je créer un nouvel opérateur en C++ et comment?
MATLAB matrices matrice de prise en charge des opérations et de l'élément d'opérations. Par exemple, M*N
et M.*N
. C'est assez intuitif façon de distinguer les deux types d'opérations. Si je veux mettre en œuvre des opérations similaires en C++, comment puis-je le faire?
Puis-je créer un nouvel opérateur, .*
, trop? Si oui, quelqu'un peut-il me donner quelques conseils?
- Voulez-vous dire que vous voulez surcharge
*
? Ou vous souhaitez créer un opérateur avec un symbole différent? - je veux créer un nouvel opérateur .* (dot se multiplient)
- A ma réponse répondent pas à votre question?
- je vous remercie pour votre réponse. Il aide.
- Jetez un oeil à cette belle bibliothèque: github.com/klmr/named-operator, il est facile de faire votre propre nommée opérateurs.
- Je suis curieux de savoir, ce qui est confus au sujet de l'excellente page que dalle lié à ce que vous ressentiez le besoin d'offrir une prime de demander quelque chose de nouveau (que la question d'origine n'a pas demandé)?
- N'est-ce pas, c'est inquiétant que les migrants provenant d'une autre langue toujours essayer de re-cast C++ pour permettre des opérations dans la façon dont ils sont utilisés pour? Je me demande pourquoi ils ne restent pas, mais viennent du C++? Je trouve la syntaxe MATLAB dans le post pas du tout intuitif (je n'ai aucune idée de ce qu'ils pourraient peut-être dire, à part peut-être à partir de la matrice de multiplication).
- vous avez besoin de délimiteurs. littleadv lié à une bibliothèque qui peut le faire sans délimiteurs, mais son code est en désordre. Bounty va à celui qui peut déchiffrer.
- OMI, vous devriez avoir posé une nouvelle question. Ce n'est pas ce que l'OP n'a pas de demander.
Vous devez vous connecter pour publier un commentaire.
Non, vous ne pouvez pas surcharger
op.*
:sizeof()
ettypeid()
op.*
ne peut pas être surchargé, car c'est ce que l'OP a une question sur.En C++, il y a une liste des opérateurs prédéfinis, dont la plupart sont overloadable (.* ne l'est pas). En outre, tout nom peut être utilisé comme un opérateur comme:
Avertissement: Ce, à proprement parler, se traduit à
(5 < myop) > 2
, qui estLHSlt<int, decltype(myop)>(5) > 2
. Ainsi, il n'est pas un nouveau "opérateur", en C++, mais il est utilisé exactement de la même façon, même dans les conditions de l'ADL. Aussi, si le type est grand, vous voudrez probablement pour stockerconst T&
.Notez que vous pouvez le faire avec n'importe quel opérateur binaire qui peut être définie externe à la classe; la priorité est basée sur la priorité des deux côtés (
<
et>
). Ainsi, vous pouvez avoir par exemple*myop*
,+myop+
,<<myop>>
,<myop>
,|myop|
dans cet ordre de préséance.Si vous voulez à droite-associativité, il devient un peu plus délicat. Vous aurez besoin à la fois d'une ERS-titulaire et LHS-titulaire (le dernier étant
LHSlt
ici) et l'utilisation environnant les opérateurs tels que celui de droite a une priorité plus élevée que celle de gauche, par exemplea |myop> b |myop>c
esta |myop> (b |myop> c)
. Ensuite, vous avez besoin de la fonction de votre type et votre type de support comme de gauche.Vous ne pouvez pas surcharger
.*
(voir La légèreté " répondre de texte standard), mais, curieusement, vous peut surcharge->*
(similaire à la façon dont vous pouvez surcharge->
mais pas.
). Si cela est suffisant pour la différenciation, alors à elle:Que vais imprimer
Int(30), Int(11)
..*
, mais la bonne réponse, de toute façon.Comme pour la première partie, vous pouvez surcharger la plupart des opérateurs et il ya certains que vous ne pouvez pas la surcharge et la liste des opérateurs en C++ sont:
Arithmétique
+ (addition)
- (subtraction)
* (multiplication)
/(division)
% (modulus)
Au niveau du bit
^ (XOR)
| (OR)
& (AND)
~ (Complement)
<< (Shift Left, Insertion to Stream)
>> (Shift Right, Extraction from Stream)
Affectation
= (Assignment)
Relationnel
== (Equality)
!= (Inequality)
> (Greater-Than)
< (Less-Than)
>= (Greater-Than Or Equal-To)
<= (Less-Than Or Equal-To)
Logique
! (NOT)
&& (AND)
|| (OR)
Composé D'Affectation
+= (Addition-Assignment)
-= (Subtraction-Assignment)
*= (Multiplication-Assignment)
/= (Division-Assignment)
%= (Modulus-Assignment)
&= (AND-Assignment)
|= (OR-Assignment)
^= (XOR-Assignment)
<<= (Shift-Left Assignment)
>>= (Shift-Right Assignment)
Incrément - Décrémenter - tous les Deux ont 2 formes (préfixe) et (postfix)
++ (Increment)
-- (Decrement)
Indice
[] (Subscript)
Appel De Fonction
() (Function Call)
Adresse, Référence, Pointeur
operator&()
operator*()
operator->()
Virgule
operator,()
Membre De Référence
operator->()
operator->*()
De Gestion De La Mémoire
new
delete
new[]
delete[]
Conversion
operator "type" () const
NON Modifiables Opérateurs - Exploitants qui ne peuvent pas être surchargé
?: (Conditional - Ternary)
. (Member Selection)
.* (Member Selection With Pointer To Member)
:: (Scope Resolution)
sizeof() (Object Size Information)
typeid() (Object Type Information)
Donc, sachant que cette liste vous aidera à répondre à vos questions. Pouvez-vous Créer un "Nouvelles" d'Opérateur en C++? Non! Si vous voulez mettre en œuvre des opérations similaires en C++; comment puis-je le faire?
Vous avez 4 choix: Soit la surcharge d'un opérateur qui peut être surchargé, écrire une fonction ou une méthode pour faire le type de calculs que vous souhaitez effectuer, la création d'un modèle type pour faire le travail pour vous, ou le dernier qui est le moins fréquent à faire, mais vous pouvez également écrire des macros pour les faire pour vous.
Il y a un en-tête Mathématiques de l'API de la Bibliothèque qui est utilisée assez fréquemment avec graphique OpenGL API et OpenGL du Langage de Shader GLSL et cette bibliothèque possède de nombreuses fonctionnalités que le travail avec les vecteurs, les matrices, les quaternions, etc., et toutes les fonctions nécessaires et les opérations qu'on peut faire pour eux. Voici le lien pour GLM Vous pouvez avoir un coup d'oeil à leur documentation ainsi que leurs implémentations de la bibliothèque, car il est un que les en-têtes de la bibliothèque ou de l'API. Cela devrait vous donner un aperçu sur la façon dont ils ont construit leur Matrice et Vecteur d'objets et les opérations qu'on peut faire pour eux.
Non, malheureusement, vous ne pouvez pas définir de nouveaux opérateurs—vous ne pouvez surcharger les opérateurs existants (avec quelques exceptions importantes, telles que
operator.
). Même alors, il est habituellement seulement une bonne idée de surcharger les opérateurs pour les types qui ont très clairement et sans controverse existant sémantique pour un opérateur donné—par exemple, le type qui se comporte comme un nombre est un bon candidat pour la surcharge de l'arithmétique et des opérateurs de comparaison, mais vous devez vous assurer queoperator+
n'est pas, disons, de soustraire deux nombres.BTW: je suis à la recherche pour répondre aux parties de cette question, comme l'a demandé. Je suis également ne cherche pas à reproduire toutes les informations dans d'autres réponses dignes. Le bounty cherche quelque chose de différent à la question posée, je ne suis donc pas répondre à cela.
Il est en fait assez simple de fournir une multiplication matricielle. Depuis que je suis ne propose pas de décrire des structures de données pour représenter une matrice et de mettre pleinement en œuvre les opérations et les vérifications de validité sur eux, je vais fournir des squelettes pour illustrer.
Exemple 1:
operator*()
comme une fonction membreCi-dessus met en œuvre
operator*()
comme une fonction membre. Donc, fonctionnellement,c = a*b
est équivalent àc = a.operator*(b)
. Leconst
qualificatifs de représenter le fait qu'une multiplication de matricea*b
ne fait généralement pas de changementa
oub
.Exemple 2:
operator*()
en tant que non-membre de la fonctionMaintenant,
operator*()
peut également être mis en œuvre en tant que non-membre (éventuellement unfriend
), avec un squelette qui ressemble àNoter que, dans ce cas,
a*b
est maintenant équivalent àoperator*(a, b)
.Si vous souhaitez utiliser les deux formes, de soins est nécessaire pour éviter toute ambiguïté. Si les deux formes de
operator*()
sont fournies qu'ils sont tous les deux valides matches en un énoncé commec = a*b
et le compilateur n'a aucun moyen de choisir une forme sur l'autre. Le résultat est le code de la compilation.Exemple 3: surcharge
operator*()
Il est également possible de surcharger
operator*()
- par exemple, pour multiplier une matrice par un scalaire.Ci-dessus
b*2.0
élève à un appel deb.operator*(2.0)
et2.0*a
à un appel de la non-membreoperator*(2.0, a)
. Le membre formulaires ne peuvent généralement être utilisées dans des expressions où la main gauche opérande est de typeM
. Donc2.0*a
ne fonctionnera pas si seul membre formes deoperator*()
est fourni.Discussion
En dehors des préoccupations de l'ambiguïté ci-dessus, il y a d'autres choses à connaître lors de la surcharge des opérateurs.
a+b*c
, le*
aura toujours la priorité sur l'+
. C'est aussi la raison pour laquelle il n'est pas une bonne idée de surcharge^
pour l'exponentiation en C++, car^
a une priorité plus basse que+
en C++ (qui est une opération au niveau du bit sur les types intégraux). Donca + b^c
est en fait l'équivalent en C++ pour(a + b)^c
, de ne pasa + (b^c)
(lequel n'importe qui avec des connaissances de base de l'algèbre attendez).**
en C++, tels quea ** b
soulèvea
à la puissance deb
(qui d'autres langues peut le faire), et il n'est pas possible d'en créer un.L'un des opérateurs qui ne peuvent pas être surchargés en C++ est
.*
. Donc, il n'est pas possible d'utiliser un de ces opérateurs, comme vous le feriez dans Matlab. Je voudrais généralement recommandé de ne PAS essayer d'obtenir le même effet en utilisant d'autres opérateurs, car les contraintes ci-dessus aura une incidence sur cette (et à cause des expressions pour donner des contre-intuitive du comportement). Au lieu de simplement fournir une autre fonction nommée pour faire le travail. Par exemple, en tant que membre de la fonctionLa plupart des réponses ont déjà couvertes par les opérateurs sont et ne sont pas overloadable, mais personne n'a expliqué POURQUOI certains sont mutables et certains ne le sont pas.
Ce qui suit est une citation de Bjarne Stroustrup (le gars qui a écrit en c++) que j'ai trouvé dans cette stackoverflow répondre. Payer une attention particulière à la troisième paragraphe.
Une page sur son site web ajoute un peu plus:
Ainsi, alors que la plupart des opérateurs peuvent être surchargés, il n'a été jamais prévu pour les gens à créer arbitraire des opérateurs en c++.
C'est aussi simple (et aussi difficile!) comme la définition d'une fonction appelée (dans ce cas)
operator*()
:où
Matrix
est une classe que vous avez définis pour représenter les matrices.Comme d'autres réponses-dire, d'une surcharge
operator.*
n'est pas possible.Mais j'ai eu une bonne solution pour votre question, vérifiez ici.
Vous pouvez fournir toutes les méthodes dans l'opérateur-ish formulaire comme: