Download

Operator Overloading for == returning false everytime


friend bool operator==(FMyStruct& A, FMyStruct& B)
	{
		return (A.Name == B.Name);
	}

This is the code I have placed in my struct declaration, but it is always returning false, and I can’t seem to figure out why. I am wanting to have an == operator for my struct. I have tried with and without the ampersands after the structs, and many other variations of returning my result, but nothing has worked so far, any ideas?

I guess the Name property of FMyStruct is of type FString.
In that case, you want to compare their values:


friend bool operator==(FMyStruct& A, FMyStruct& B)
	{
		return (A.Name.Compare(B.Name, ESearchCase::CaseSensitive) == 0);
	}


Even if that’s the case Jamendxman3’s code “should” work since there are operator== overloads for FString as well which performs case insensitive comparision I believe.
Are you sure the operator is used/called at all? Try setting a breakpoint or use log or onscreendebugmessage.

Nope, it is of type FName.

I just added a log message, and nothing is being logged. I was originally just using the == in blueprints, but it still did not log when used in C++.

Try :

const FMyStruct& a, const FMyStruct &b.

Also, if it is declared within structure, it should be marked as static



struct FMyStruct{
    static bool operator==(const FMyStruct &a, const FMyStruct &b);.
};


Text is now logged, but it still is returning false everytime. Here is the new code:


friend bool operator==(const FMyStruct& A,const FMyStruct& B)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Red, "OPERATOR OVERLOADED!");
		return (A.Name == B.Name);
		
	}

I’m not sure whether or not you just made a typo, but I tried both with the Ampersand to the left of B, and at the end of FMyStruct.

Edit: I receive compilation errors when using ‘Static Bool Operator==…’

“FMyStruct &a” and “FMyStruct& a” means the same thing.

Usually operator== is declared outside of the class/struct.



#include <iostream>

struct Test{
	int a;
};

bool operator==(const Test& a, const Test& b){
	return a.a == b.a;
}

int main(){
	Test a, b, c;	
	a.a = 1;
	b.a = 1;
	c.a = 2;
	
	std::cout << (a == b) << std::endl;
	std::cout << (a == c) << std::endl;

	return 0;
}


In any case, set a breakpoint in the operator== and walk through the code with debugger.
If this portion is fine, problem might be outside of it - either within FName::operator== (can be debugged with “step into”), or within code that calls FMyStruct::operator==.

I originally had the operator definition inside of the struct declaration, but am getting errors after moving it outside:
f3a9958b59d6ac92fdb4734efbefba9d8258f8c0.png

The stuff I blacked out is just either the name of my plugin or the name of my project.

8d3f72da899e97af05c955298a462f4074aced69.png

Don’t worry, I just blocked out the name of my struct, nothing important. That ^ is how I am declaring stuff.

Edit: My overload is also returning false even if I hard code in ‘return true’. I have now tried various other methods of declaring this overload, but nothing is working.

Here is another declaration method I tried (Declared outside of the struct declaration):


 FORCEINLINE bool operator==(const FMyStruct& A, const FMyStruct& B)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Red, "OPERATOR OVERLOADED!");
		return true;
		
	}

I am about to the point of tearing my hair out, can anyone tell me what I am doing wrong?

The important part is your screenshot.

Apparently you have another operator== declared somewhere, judging by screenshot it is within file called Iodes.cpp and your overload isn’t being called.

Also, if you want help, the best idea is to produce minimal example that shows your problem and post complete code for the whole struct. If you keep hiding portions of your code and blocking out names of your struct it will only take longer. If you’re wary of someone “stealing” your code, then generally something that takes less than 2…4 weeks to write is not worth stealing.

There’s also no reasl reason to forceinline operator within header, but that’s another story.

To fully diagnose the problem, insert breakpoint at the portion of the program where you’re comparing the structs and “step in” to see where execution goes.



    FMyStruct a, b;
    ...

    bool test = (a == b);//<<-- insert breakpoint here and step in.



Also, in my whole life I think I never declared 2 argument form of operator== within class.

See http://en.cppreference.com/w/cpp/language/operator_comparison

Declaration is usually done like this:



#include <iostream>

//inside class
struct Test{
	int val = 3;
	bool operator==(const Test& other) const{
		return val == other.val;
	}
};

//outside of class
struct Test2{
	int val = 3;
};

bool operator==(const Test2 &arg1, const Test2 &arg2){
	return arg1.val == arg2.val;
}

int main(int argc, char** argv){
	Test a, b, c;
	b.val = 6;
	std::cout << (a == b) << std::endl;
	std::cout << (a == c) << std::endl;
	
	Test2 a1, b1, c1;
	b1.val = 6;

	std::cout << (a1 == b1) << std::endl;
	std::cout << (a1 == c1) << std::endl;
}


Hmm, I assure you I have not used operator== anywhere else. I am quite confused by the examples you gave for declaration. Why is a ‘2’ appended to the struct name? By inside class, you mean inside of the


class MYCLASS_API ....... : public ..........

? What is int main? I am also unaware of how to use breakpoints if the operator overload is used as a blueprint node, and no code is ran with Visual Studio.

Edit: After doing a little bit of testing (and several Visual Studio freezes -> PC hard reset), I figured out how to debug my c++ code. I have placed a breakpoint on the line that has return in my .h file, and it is never hit. I also tried placing a breakpoint on the line that uses the comparison in my CPP file, but get an error saying that no symbols have been loaded for this document, and it forces the breakpoint down onto the next line, any ideas?

Have you checked that file I mentioned?

It is different type name. Numbers can be used in class and structure type names as long as the type name doesn’t start with a numnber. “struct S102384563” is a valid type name.

Means at any point



UCLASS()
class MYCLASS_API MyClass{
     GENERATED_UCLASS_BODY()

     //<===== here
};


past opening brace and before closing brace in class declaration.

Program entry point. When you’re compiling standalone C++ program, it must have int main. (well, on windows it can require WinMain, but that’s different story).

“Attach to process” (to unreal4 editor process) via debug menu, and wait for the program to hit breakpoint once symbols are done loading.

You forgot to mention that part, and you’ll need to show how you’re doing comparison within blueprints.

You can only debug the line if it is called by something. You also need debug ore development build. If the line is never used, compiler can optimize it away.

I suggest to take a break for couple of days and spend that time reading C+±related tutorials. You’re missing a lot of basic info at the moment (“what is int main”, “number in type names”, “how to use breakpoints”, etc). Can’t recommend any tutorials, since its been many years since I needed any.

That file is a .obj file with nearly unreadable text (or I just don’t know what to open it with). If there is another mention of == somewhere, I didn’t put it there.

As in it’s the same thing, but a variation? I am not seeing much about numbers & typenames online.

0910bc2a07.png
I have also tried many variations/setups of using the node.

I assure you I know how to debug with breakpoints, I just wasn’t aware that I could debug blueprint nodes, as every time I’ve tried, VS freezes my computer, and even did it a few times last night. The problem is that it is very hard to tell what applies to UE4 where C++ is concerned. I spent about 3 months learning straight C++, and so far none of that has really been used in UE4.

Edit: I guess I should also mention that my code is contained in a plugin, in case that matters.

e2dd02da84ab387bf8fca9f5ff7efa4edbcf0208.png

This is an area in my .cpp file in one of my functions that I occasionally call, the breakpoint is always forced off of the comparison line downwards.

*.obj file corresponds to *.cpp file. If it says that Whatever.obj contains another definition, you can check Whatever.cpp to which *.obj file corresponds. You should’ve known that already.

No. In original example the name of the type was “Type2”. Literally.
C++ identifier (that can be used to name types, functiosn, namespaces, etc) can contain mix of letters, numbers and underscore characters, as long as it is doesn’t start with a number and doesn’t match language keyword.

Each blueprint node corresponds to some C++ code. You can debug that code. You can also debug entire engine.

o_O
I have no idea how this could possibly be true.

If you’re running non-debug and non-development configuration, compiler may remove the line away, because result isn’t used anywhere.


So I wasted 15 minutes of my time and ran a test.

*.h:



USTRUCT(BlueprintType)
struct FTestStruct{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FName testName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 testInt = 0;
};

inline bool operator==(const FTestStruct &arg1, const FTestStruct &arg2){
	return (arg1.testName == arg2.testName) && (arg1.testInt == arg2.testInt);
}

UCLASS()
class MYGAME_API UTestStructLib: public UBlueprintFunctionLibrary{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintPure, meta=(DisplayName = "Equal Test Struct", CompactNodeTitle = "==", Keywords = "== equal"), Category="Math")
	static bool EqualEqual_TestStructTestStruct(const FTestStruct &arg1, const FTestStruct &arg2);
};


*.cpp:



bool UTestStructLib::EqualEqual_TestStructTestStruct(const FTestStruct &arg1, const FTestStruct &arg2){
	return arg1 == arg2;
}



The code is within “game engine” portion of code, because there was no point in putting that into separate plugin.

I can confirm that this works just fine.

First, operator== is not automatically exposed to the blueprints. You need to make a binding to ufunction. Error most likely happens in that binding.

Recheck your binding code and check if both values are plugged in. As far as I can tell, blueprint shouldn’t even compile unless both input nodes are plugged in.

I really appreciate you taking the time to help. I’m over here smiling like an idiot because IT WORKS! I swear I had the same setup as you(except I didn’t use ‘inline bool’), but I replicated what you had, and it’s exactly what I need! Thanks for sticking around to help my unknowledgeable self. I apologize if I was being difficult, or simply dumb, but thanks!

Sure, have fun.

I’m not entirely certain how smart compilers are with that but since you’re comparing the thing to itself operator== should always just return true.