C++/CLI 템플릿 클래스에서 연산자 오버로딩 문제

  • Post author:
  • Post category:
  • Post comments:8 Comments
  • Post last modified:February 7, 2020

아무래도 컴파일러 버그인 듯한 문제를 발견했는데, 단순히 내 자신이 무지한 탓인가 싶어 블로그에 올려봅니다. 소스 코드는 Visual Studio 2008로 작성해서 올려놨습니다.

// LibraryA.cpp : library file.
#include "stdafx.h"
#include <iostream>

using namespace System;

template<typename ABC>
public ref class ManagedClassA
{
public:
	int V;

	ManagedClassA(int v)
	{
		V = v;
	}

	static bool operator == (ManagedClassA^ a, ManagedClassA^ b)
	{
		// Return true if the fields match:
		return ( (a->V + b->V) % 2 == 0 );
	}

	static bool operator != (ManagedClassA^ a, ManagedClassA^ b)
	{
		return !(a == b);
	}
};

public ref class ManagedClassB : public ManagedClassA<int>
{
public:
	ManagedClassB(int v)
		: ManagedClassA(v)
	{
	}
};

// 단순 테스트용 클래스
public ref class Tester
{
public:
	static void Test1()
	{
		ManagedClassB^ b1 = gcnew ManagedClassB(1);
		ManagedClassB^ b2 = gcnew ManagedClassB(3);
		if(b1 == b2)
			System::Console::WriteLine("성공");
		else
			System::Console::WriteLine("실패");
	}
};


template<typename ABC>
public ref class ManagedClassC
{
public:
	int V;

	ManagedClassC(int v)
	{
		V = v;
	}

	static bool operator == (ManagedClassC^ a, ManagedClassC^ b)
	{
		// Return true if the fields match:
		return ( (a->V + b->V) % 2 == 0 );
	}

	static bool operator != (ManagedClassC^ a, ManagedClassC^ b)
	{
		return !(a == b);
	}
};

public ref class ManagedClassD : public ManagedClassC<int>
{
public:
	ManagedClassD(int v)
		: ManagedClassC(v)
	{
	}
};
// LibraryB.cpp : main project file.
#include "stdafx.h"

using namespace System;

void Test2()
{
	ManagedClassD^ b1 = gcnew ManagedClassD(1);
	ManagedClassD^ b2 = gcnew ManagedClassD(3);
	if(b1 == b2)
		System::Console::WriteLine("성공");
	else
		System::Console::WriteLine("실패");
}

int main(array<System::String ^> ^args)
{
	Tester::Test1();
	Test2();
    return 0;
}

LibraryA는 dll로 빌드한 닷넷 어셈블리고, LibraryB는 콘솔 애플리케이션입니다. 여기서 주목할 것은 LibraryA의 클래스 A, B와 클래스 C, D입니다. 두 코드는 동일합니다. 클래스 A와 클래스 C, 그리고 클래스 B와 클래스 C는 완전히 똑같습니다. 글쎄요. 차이점이 뭘까요? 단 하나입니다. 클래스 A와 B의 연산자 오버로딩을 테스트하는 코드는 LibraryA에 있지만, 클래스 C와 B를 테스트하는 코드는 LibraryB에 있습니다. 얼핏 생각하기엔 완전히 같은 코드지만 실제로 돌려보면 그렇지가 않습니다. 과연 어떤 결과가 나올까요?

성공
실패

테스트 코드가 LibraryA에 있으면 성공하지만 그렇지 않으면 실패합니다. 이게 도대체 어떻게 된 일일까요? 컴파일된 코드를 까보면 문제가 확실해집니다. Reflector를 이용해 컴파일된 코드를 열어봅니다.

C++/CLI 템플릿 클래스에서 연산자 오버로딩 문제

ClassA엔 연산자 오버로딩한 메서드 op_Equality가 있지만, ClassB엔 없습니다.

자, 이게 도대체 무슨 영문일까요? 컴파일러가 바보인가요? 아니면 제가 당연한 걸 모르는 건가요?

PS. C++/CLI에서의 연산자 오버로딩 패턴에 해결책을 적었습니다.

Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.
follow me
  • 싸이월드 법인가 뭔가 화제였는데 이런 게 훨씬 현실적인 접근이다 https://t.co/fSB9LiMYzO
    1 day ago
  • 시장을 좋게 보는 사람을 좋게 볼 근거를 찾고 그렇지 않은 사람은 나쁘게 볼 근거만 열심히 찾네. 그 반대로 해야 얻는 게 있을텐데
    1 day ago
  • 일본이 liberal country 라는 말이 마음에 걸리네 https://t.co/aLteP9gEE8
    2 days ago
Buy me a coffeeBuy me a coffee
×
Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.
Latest Posts