What causes a 'no operator matches these operands' error?

C++ Fejl: 'no operator matches these operands'

03/02/2008

Rating: 4.43 (1349 votes)

At støde på en fejlmeddelelse under kompilering kan være en af de mest frustrerende oplevelser for en udvikler, uanset erfaringsniveau. En af de mest almindelige, og til tider forvirrende, fejl i C++ er 'no operator matches these operands'. Ved første øjekast kan denne besked virke kryptisk, men i virkeligheden er det kompilatorens måde at fortælle dig, at den ikke forstår den operation, du beder den om at udføre. Den fortæller dig, at du forsøger at bruge et symbol (en operator) på en eller flere datatyper (operander), som den ikke har en foruddefineret regel for. Denne artikel fungerer som en dybdegående guide til at diagnosticere, forstå og behandle denne specifikke 'sygdom' i din C++ kode.

Does googletest have a matcher library?
Actual: "Hi, world!" GoogleTest provides a built-in library of matchers—see the Matchers Reference. It is also possible to write your own matchers—see Writing New Matchers Quickly. The use of matchers makes EXPECT_THAT a powerful, extensible assertion.
Indholdsfortegnelse

Forstå diagnosen: Hvad betyder fejlen egentlig?

For at kunne løse problemet er vi nødt til at dissekere selve fejlmeddelelsen. Den består af to centrale dele: 'operator' og 'operands'.

  • Operator: Dette er det symbol, der udfører en handling. Det kan være aritmetiske operatorer som +, -, *, /, sammenligningsoperatorer som ==, !=, <, >, eller endda mere komplekse operatorer som stream-indsættelsesoperatoren << eller array-indeksering [].
  • Operander: Dette er de værdier eller variable, som operatoren virker på. I udtrykket 5 + 3 er + operatoren, og 5 og 3 er operanderne.

Fejlen 'no operator matches these operands' opstår, når C++ kompilator ikke kan finde en indbygget regel eller en brugerdefineret definition for, hvordan den specifikke operator skal opføre sig med de givne operanders datatyper. C++ er et stærkt typet sprog, hvilket betyder, at enhver variabel har en bestemt type (f.eks. int, double, std::string, eller en brugerdefineret klasse), og sproget har strenge regler for, hvordan forskellige typer kan interagere. Kompilatoren forsøger at sige: 'Jeg ved, hvad + betyder for to tal, men jeg aner ikke, hvad det betyder at lægge et tal og en bil sammen.'

Almindelige årsager og symptomer

Denne fejl kan manifestere sig i mange situationer. Lad os se på de mest almindelige årsager, så du hurtigt kan genkende symptomerne i din egen kode.

1. Mismatch mellem fundamentale typer

Den mest simple årsag er et forsøg på at udføre en operation mellem to inkompatible, fundamentale datatyper. For eksempel ved kompilatoren ikke, hvad den skal gøre, hvis du prøver at lægge et heltal og en tekststreng sammen direkte på denne måde:

#include <string> int main() { int antalAebler = 5; std::string besked = " æbler"; // FEJL: Kan ikke lægge en int og en std::string sammen med '+' // std::string resultat = antalAebler + besked; return 0; }

Her ved + operatoren, hvordan man lægger to tal sammen, og den ved, hvordan man sammenkæder to strenge, men der er ingen indbygget regel for at blande de to.

2. Brug af operatorer på brugerdefinerede klasser (Objekter)

Dette er den hyppigste årsag til fejlen for C++ udviklere, der arbejder med objektorienteret programmering. Forestil dig, at du har en klasse til at repræsentere en 2D-vektor:

class Vektor2D { public: float x, y; }; int main() { Vektor2D position1 = {10.0f, 20.0f}; Vektor2D position2 = {5.0f, 5.0f}; // FEJL: Kompilatoren ved ikke, hvordan man lægger to Vektor2D-objekter sammen. // Vektor2D totalPosition = position1 + position2; return 0; }

Selvom det for et menneske er logisk, at man skal lægge x- og y-komponenterne sammen, har C++ ingen anelse om dette. Du har defineret en ny type, Vektor2D, men du har ikke fortalt kompilatoren, hvad + operatoren betyder for denne type.

3. Forsøg på at udskrive komplekse typer til en stream

En anden klassiker er at forsøge at udskrive et komplekst objekt, som f.eks. en std::vector eller din egen klasse, direkte til std::cout.

#include <iostream> #include <vector> int main() { std::vector<int> tal = {1, 2, 3, 4, 5}; // FEJL: Der findes ingen overload af '<<' for std::cout og std::vector<int> // std::cout << tal << std::endl; return 0; }

Kompilatoren kender << operatoren for simple typer som int, double og const char*, men den ved ikke, hvordan den skal formatere og udskrive indholdet af en hel vektor.

Behandlinger: Effektive løsninger på problemet

Nu hvor vi har diagnosticeret problemet, lad os se på de forskellige 'behandlinger', der kan kurere din kode.

Løsning 1: Eksplicit typekonvertering

For problemet med fundamentale typer er løsningen ofte at konvertere en af operanderne til en type, der er kompatibel med den anden. I eksemplet med æblerne kan vi konvertere heltallet til en streng, før vi forsøger at sammenkæde dem.

#include <string> #include <iostream> int main() { int antalAebler = 5; std::string besked = " æbler"; // LØSNING: Konverter int til string først std::string resultat = std::to_string(antalAebler) + besked; std::cout <lt; resultat << std::endl; // Udskriver "5 æbler" return 0; }

Løsning 2: Operatoroverload (Den kraftfulde kur)

For brugerdefinerede klasser er den korrekte og mest elegante løsning at implementere det, der kaldes operatoroverload. Dette betyder, at du selv definerer, hvad en operator skal gøre, når den anvendes på objekter af din klasse. Du 'overloader' operatorens standardfunktionalitet med din egen logik.

Lad os løse vores Vektor2D problem ved at overloade + operatoren:

#include <iostream> class Vektor2D { public: float x, y; // Overload af + operatoren for Vektor2D Vektor2D operator+(const Vektor2D& anden) const { Vektor2D resultat; resultat.x = this->x + anden.x; resultat.y = this->y + anden.y; return resultat; } }; int main() { Vektor2D position1 = {10.0f, 20.0f}; Vektor2D position2 = {5.0f, 5.0f}; // NU VIRKER DET! Kompilatoren finder vores overloadede operator. Vektor2D totalPosition = position1 + position2; std::cout << "Resultat: (" << totalPosition.x << ", " << totalPosition.y << ")" << std::endl; return 0; }

Ved at tilføje funktionen operator+ inde i klassen har vi nu lært kompilatoren, hvordan man lægger to Vektor2D objekter sammen. Den samme teknik kan bruges for -, *, == og mange andre operatorer for at gøre din klasse mere intuitiv at bruge.

Løsning 3: Manuelle metoder eller hjælpefunktioner

For problemet med at udskrive en std::vector er den simple løsning at iterere gennem den med en løkke:

#include <iostream> #include <vector> int main() { std::vector<int> tal = {1, 2, 3, 4, 5}; // LØSNING: Brug en løkke til at udskrive hvert element for(int t: tal) { std::cout << t << " "; } std::cout << std::endl; return 0; }

En mere avanceret, men genanvendelig løsning, ville være at overloade << operatoren for std::ostream og std::vector. Dette gøres typisk som en fri funktion uden for klassen.

Sammenligningstabel: Almindelige fejlscenarier

Fejlkode (Eksempel)Mulig ÅrsagLøsning
int i = 5; std::string s = "t"; auto res = i + s;Forsøg på at bruge '+' på inkompatible fundamentale typer (int og string).Konverter den ene type til den anden, f.eks. med std::to_string(i).
MyClass a, b; MyClass c = a + b;Klassen 'MyClass' har ikke en defineret måde at håndtere '+' operatoren på.Implementer operatoroverload for '+' operatoren inde i 'MyClass'.
std::vector<int> v; std::cout << v;'<<' operatoren er ikke defineret for std::ostream og std::vector.Iterer gennem vektoren med en løkke og udskriv hvert element individuelt.

Ofte Stillede Spørgsmål (FAQ)

Hvorfor kan jeg godt lægge en `int` og en `double` sammen, men ikke en `int` og en `std::string`?
C++ har indbyggede regler for 'promovering' mellem numeriske typer. Når du lægger en int og en double sammen, bliver din int automatisk og sikkert konverteret til en double, før additionen udføres. Der findes ingen sådan sikker, indbygget konvertering mellem en int og en std::string, da intentionen er uklar. Skal tallet være tekst, eller skal teksten være et tal?
Er operatoroverload en dårlig praksis?
Nej, det er en meget kraftfuld og central del af C++. Når det bruges korrekt, gør det koden mere læsbar og intuitiv (som at bruge + til at addere vektorer). Det kan dog misbruges. En god tommelfingerregel er kun at overloade en operator, hvis dens betydning er fuldstændig klar og utvetydig i konteksten af din klasse. At overloade + til at slette en fil ville være et eksempel på ekstremt dårlig praksis.
Gælder denne fejl kun for matematiske operatorer?
Absolut ikke. Fejlen kan opstå med næsten enhver operator i C++, herunder == (sammenligning), [] (array-adgang), -> (medlemsadgang via pointer), () (funktionskald) og <</>> (stream-operatorer). Løsningen er den samme: Sørg for, at der findes en definition for, hvordan operatoren skal opføre sig med de givne operander, enten via indbyggede regler, typekonvertering eller operatoroverload.

At mestre forståelsen af 'no operator matches these operands' er et vigtigt skridt i rejsen mod at blive en mere kompetent C++ udvikler. Ved at tænke på det som en klar besked fra kompilatoren – en anmodning om instruktioner – kan du omdanne frustration til en produktiv problemløsningsproces og skrive mere robust og udtryksfuld kode.

Hvis du vil læse andre artikler, der ligner C++ Fejl: 'no operator matches these operands', kan du besøge kategorien Teknologi.

Go up