(C++) Override FArchive virtual operator<< for FName

(UE4-23) We have in Archive.h

class CORE_API FArchive
{
public:
	virtual FArchive& operator<<(FName& Value)
	{
		return *this;
	}

Normally it’s overrided in somewhere like LinkerLoad.h, which is for package.
Now I’m doing something generic outside of LinkerLoad, and I’m trying to use
FArchiveFileReaderGeneric and FArchiveFileWriterGeneric and it’s ok for TArray/TMap.

Since I need an operator<< override for FName, when I added this in FArchiveFileReaderGeneric:

class CORE_API FArchiveFileReaderGeneric : public FArchive
{
public:
	...
        virtual FArchive& operator<<(FName& Value) final
	{
		FNameEntryId	comparisonIndex;
		FNameEntryId	displayIndex;
		uint32			number;
		*this << comparisonIndex;
		*this << displayIndex;
		*this << number;
		Value = FName(comparisonIndex, displayIndex, number);
		return *this;
	}

And turned out, it can’t resolve to the derived<< with the following

			FArchive* ia = IFileManager::Get().CreateFileReader(*archiveFile);
			FName test;
			(*ia).operator<<(test); //base<<
			(*ia) << test; //base<<

So I changed it to

			FArchiveFileReaderGeneric& ia = *static_cast<FArchiveFileReaderGeneric*>(IFileManager::Get().CreateFileReader(*archiveFile));
			FName test;
			ia.operator<<(test); //derived<<, but only with 'final', not 'override'
			ia << test; //base<<

Finally my question is, how should I design it so
that ia << test; will go to the derived << implementation? Thanks.

I wonder if my C++ understanding is flawed, so I wrote a trivial test:

//header
#include <string>
constexpr int	BUF_SIZE = 256;

class FArchive
{
public:
	FArchive() : index(0)
	{
		std::memset(buf, 0, sizeof(char) * BUF_SIZE);
	}
	virtual ~FArchive() {}
public:
	virtual FArchive& operator<<(const char* Value)
	{
		return *this;
	}
public:
	int	index;
	char buf[BUF_SIZE];
};

class FArchive2 : public FArchive
{
public:
	FArchive2() {}
	~FArchive2() {}
	virtual FArchive& operator<<(const char* Value) override
	{
		const int len = std::strlen(Value);
		if (index + len < BUF_SIZE)
		{	
			std::strncat(buf, Value, len);
			index += len;
		}
		return *this;
	}
};

And test it like this

#include <string>
#include <iostream>
#include "VirtualMemberOperatorOverride.h"

int main()
{
	const char* test = "test1";
	FArchive* ar = new FArchive2();
	*ar << test; //derived<<
	delete ar;

	FArchive2 ar2;
	FArchive& arr = ar2;
	arr << test; //derived<<

	std::cin.get();
}

And bingo! Both can resolve to the derived<< implementation!

So why this

virtual FArchive& operator<<(FName& Value) override

is unable to call the derived<< ?
I’m baffled and need help. Thanks!

I’ve noticed that in the UE source code, they specify this line before the operator overloads:

// Avoid hiding non overrided overloads
using FArchive::operator<<;

I’ve noticed it too in class FArchiveUObject, however adding this line into
FArchiveFileReaderGeneric/FArchiveFileWriterGeneric doesn’t solve the issue.