목록Language (73)
Coding Memo
C++20에서 추가된 Concepts의 기능인 requires에 대해서 간단히 정리해보자. requires는 C#에 비유하자면 where와 비슷한 키워드라고 생각할 수 있을 것 같다.where가 C#에서 제레릭 타입에 대한 조건을 지정하듯이,C++에서도 템플릿 타입에 대해 조건을 지정할 수 있다. Concepts 도입 전에는 SFINAE(Substitution Failure Is Not An Error)를 이용해, 템플릿 타입을 제약했었다. 그러나 C++20 이후에는, 템플릿에서 requires를 이용하여 타입에 대한 제약 조건을 쉽고 직관적으로 지정할 수 있다. 먼저 일반적인 코드를 확인해보자.struct A {};template T add(T a, T b){ return a + b;}int main(..
싱글턴 디자인 패턴은 어플리케이션 전체에서 단 하나만 존재해야하는 인스턴스를 위한 패턴이다. 특정 인터페이스를 제공한다거나 동일한 데이터를 사용할 때 한번만 로드할 때 사용한다. 보통은 전역적으로 접근 가능한 인스턴스를 사용한다. 또, 어플리케이션 시작 시점에 인스턴스를 로드할지, 이후에 사용할 때 로드 할지 (Lazy Intialization) 잘 고려하면 될 것이다. 싱글턴 패턴 구현은 언어와 개발 환경에 따라 크게 달라지는 것 같다.인스턴스를 1개로 제한하는 방법에는 인스턴스 카운트를 관리하는 코드를 추가하거나, static 전역 변수를 두어 이 인스턴스를 반환하여 사용하는 메서드를 만들면 될 것이다.보통 후자의 방법이 많이 사용되는 것 같다. 먼저 구현하는 코드를 살펴보자. struct Singl..
에서 제공하는 std::sort 함수는 지정된 조건에 맞게 정렬을 해주는 함수이다.vector나 배열에서 사용은 많이 해보았을 것이라 생각한다. 그렇다면 std::sort는 과연 어떤 인자를 받고 있을까? 이 글에서는 std::sort의 작동방법과 왜 std::list에서는 사용할 수 없는지 알아보겠다.(Visual Studio MSVC 기준이다.)std::sort 이 함수는 헤더 파일에 다음과 같이 정의되어 있다._EXPORT_STD template _CONSTEXPR20 void sort(const _RanIt _First, const _RanIt _Last, _Pr _Pred) { // order [_First, _Last) _Adl_verify_range(_First, _Last); c..
C++17부터 추가된 파일 시스템 라이브러리에서 파일과 디렉터리에 관한 여러가지 유틸을 사용할 수 있다.자주 사용할 것 같은 메서드와 멤버 변수들을 간단하게 정리해 보았다.HeaderfilesystemNamespacestd::filesystem1. 현재 경로 (working directory, current path) current_path()현재 실행중인 경로(working directory)를 반환한다. (return: std::filesystem::path)참고로, 반환된 경로는 절대 경로(absolute path)이다. current_path(const std::filesystem::path& p)현재 경로를 p로 변경한다. (return: void)마찬가지로 p가 상대경로로 지정했더라도 curr..
Dynamic Library (dll) - dllexport / dllimport (MSVC)__declspec(dllexport)와 __declspec(dllimport)는 MSVC(Microsoft Visaul C++) 컴파일러에서 사용하는 키워드이다. 동적 라이브러리(dynamic library)에서 클래스나 메서드, 변수를 내보내거나 가져올 때 사용된다.(보통 Windows에서 사용하고, GCC나 Clang에서는 __attribute__((visibility("default"))) 등을 사용) 간단히 말하면, 라이브러리에서 dll을 빌드할 때는 __declspec(dllexport) 키워드를 클래스 이름이나 메서드 원본 앞, 멤버 변수 앞 등에 붙여서 해당 내용을 외부에서 사용하도록 내보내겠다는 ..
3가지 직렬화를 비교해보자. 1. BitConverter를 이용2. Unsafe 코드인 StructureToPtr을 이용하여 메모리 내용을 그대로 이용3. 직접 바이트를 조작속도 비교 C++로 작성된 서버와 C#으로 작성된 클라이언트의 통신에서 패킷 정보 파싱을 위해 PacketHeader라는 구조체를 이용했다. PacketHeader는 unsigned int16 (ushort)의 Id 값과 같은 타입의 Size로 이루어져 있다. C++의 placement new를 이용해서 메모리에 있는 값 그대로 전송하여 C#에서 파싱하는 형태이다. PacketHeader는 다음의 구조이다.[Size, 2 bytes][Id, 2 bytes] C#에서도 위 메모리 순서를 지키면서 다음 구조체를 작성하였다.[StructL..
문제 소켓이 연결이 되었음에도 불구하고, getpeername() 함수가 SOCKET_ERROR를 반환하고, WSAGetLastError() 값이 10057(WSAENOTCONN)이었다. 해당 소켓에 대해 WSASend 및 WSARecv는 정상적으로 작동하였고, getsockname또한 정상적으로 작동하였다. 해결 연결된 소켓에 대해 SO_UPDATE_CONNECT_CONTEXT 옵션을 설정해 주면 된다.이후 getpeername은 정상적으로 작동하고, remote endpoint의 주소와 포트 번호를 가져올 수 있다. 설명 SO_UPDATE_CONNECT_CONTEXT는 소켓이 연결 된 이후에, 소켓의 속성을 업데이트하는 옵션이다. 이 옵션은 ConnectEx, WSAConnectByList, WSA..
윈도우에서 지원하는 concurrent에 대한 자료구조 헤더가 있는데, 이들은 lock-free로 구현되어 있으니 이 쪽을 사용하는 것이 훨씬 더 도움이 될 수도 있겠다 ㅋㅋ std::mutex를 이용한 lock과 std::priority_queue를 사용하여 간단한 concurrent 우선순위 큐를 만들어보았다.기본적인 push 및 pop 외에, 지정된 조건에 따라 결과값을 반환하는 TryPop등의 함수도 포함했다.상황에 따라 필요할 수도 있기 때문이다. (예를 들어, top의 객체를 확인하고 이 객체가 어떤 조건이 맞을 경우에만 pop을 해야할 필요가 있을 때, top과 pop을 따로하면 atomic하게 실행시켜야되는 데, 이 과정에서 외부 lock을 걸어야 되기 때문이다.) 추가적으로, 이동연산자를..