본문 바로가기

개발/C++

C++ 을 Python 처럼

최근 파이썬 코드를 C++로 포팅해야하는 일이 생겼다.


그렇게 하기 위해선 파이썬 코드와 동일한 C++의 STL을 알 필요가 있었다. 


다음의 1개의 웹문서와 1개의 책을 이용해 다음과 같이 정리할 수 있었다.


참고문헌 : 


웹문서 : http://preshing.com/20141202/cpp-has-become-more-pythonic/


책 : C++ 11 STL 프로그래밍 (최흥배 저)




1. 상수 (Literals)


C++ 14 부터 바이너리 상수를 제공한다. 방식은 파이썬과 동일하다.


 파이썬

 primes = 0b10100000100010100010100010101100 ( = bin(2693408940))

 C++

 static const int primes = 0b10100000100010100010100010101100;



C++ 11 부터 raw string 상수를 지원한다.


 파이썬

 path = r"c:\this\string\has\backslashes"

 C++

 const char* path = R"(c:\this\string\has\backslashes)";



2. For문 (Range-Based For Loops)


리스트에서 한 개씩 불러올 때 좀 더 편리한 방식의 For문을 사용한다.


 파이썬

 for x in myList :

     print(x)

 C++

 for (int x : myList)

     std::cout << x;



3. Auto


파이썬에는 자료형을 지정해주지 않더라도 자동으로 입력하는 값에 따라 설정된다.


하지만 C++은 선언 시 무조건 자료형을 선언해주어야 한다. 


하지만 C++11부터 Auto 라는 키워드가 추가되어 굳이 자료형을 지정하지 않아도 컴파일 시 자동으로 설정되게 할 수 있다.


 파이썬

 x = "Hello world!"

 print(x)

 C++

 auto x = "Hello world!";

 std::cout << x;



4. Tuples


파이썬에서 구조체를 쓰지 않더라도 여러개 인자를 하나로 묶어서 주고 받을 수 있는 방법이 있다. 바로 Tuple인데 C++에서도 이것을 제공한다. C++11 부터 make_tuple 함수를 이용해 튜플을 만들 수 있다. 


 파이썬

 triple = (5, 6, 7)

 print(triple[0])

 x, y, z = triple

 C++

 auto triple = std::make_tuple(5, 6, 7);

 std::cout << std::get<0>(triple);

 std::tie(x, y, z) = triple;




5. List (Uniform Initialization)


파이썬에서는 list 도 하나의 타입이다. 그리고 쉽게 선언하고 사용이 가능하다. C++에서는 vector을 이용해 파이썬의 list와 비슷하게 사용할 수 있다. 


 파이썬

 myList = [6, 3, 7, 8]

 myList.append(5);

 C++

 auto myList = std::vector<int>{ 6, 3, 7, 8 };

 myList.push_back(5);



5. Dictionary (Uniform Initialization)


파이썬에서 Dictionary 또한 하나의 타입이다. C++에서는 map 또는 unordered_map을 이용해 파이썬의 딕셔너리와 비슷하게 사용할 수 있다. 


 파이썬

 myDict = {5: "foo", 6: "bar"}

 print(myDict[5])

 C++

 auto myDict = std::unordered_map<int, const char*>{ { 5, "foo" }, { 6, "bar" } };

 std::cout << myDict[5];



6. Lamdba


람다는 이름 없는 함수라고도 불리며 반복적인 행위를 하기 위해선 외부에 함수를 선언할 수 밖에 없는 한계점을 해결하고자 파이썬에서 1994년부터 제공되었고 C++ STL에서도 이를 제공한다. 람다는 코드 내부에서 함수 선언이 가능하며 함수의 이름을 굳이 선언할 필요가 없으므로 다음과 같은 표현식을 이용해 코드를 작성하면 된다.


[] : labda capture (함수 밖에 있는 변수를 가져다 쓰기 위해 사용한다)

     & : 참조로 전달(람다 식을 정의한 범위 내에 있는 모든 변수 캡쳐 가능)

     변수이름 : 복사로 전달

     = : 외부의 모든 변수를 복사하여 캡쳐

     mutable 키워드 : 복사로 캡쳐한 변수를 람다 내부에서 변경해야할 경우 사용

() : 함수의 인수 정의 (생략 가능)

-> 리턴타입 : 만약 생략될 경우 void로 취급한다. 

{} : 함수의 본체

(); : 함수 호출


ex) 람다 사용 예제

 

int n1, n2, n3, n4, n5;

[=, &n1, &n2]{}; // n3,n4,n5는 복사, n1, n2는 참조

[&, n1, n2]{}; // n3,n4,n5는 참조, n1,n2는 복사


다음 예제는 리스트의 절대값으로 정렬하는 코드이다.


 파이썬

 myList.sort(key = lambda x: abs(x))

 C++

 std::sort(myList.begin(), myList.end(), [](int x, int y)
 { return std::abs(x) < std::abs(y); });


statically nested scopes 은 생략했다. 위의 블로그를 참조하시길.



7. Filter


파이썬에서 리스트로부터 원하는 값만 취하기 위해 filter 함수를 사용한다. C++ 에서는 copy_if를 사용한다. 다음은 리스트 내에서 양수의 값만 받아 리스트로 저장하는 코드이다.


 파이썬

 result = filter(lambda x: x >= 0, myList)

 C++

 auto result = std::vector<int>{};

 std::copy_if(myList.begin(), myList.end(), std::back_inserter(result), [](int x)

 { return x >= 0; });



8. Parameter Packs


파이썬은 임의의 아규먼트리스트를 제공한다. 이는 C++ 또한 지원하는데 파이썬과 다르게 이를 대표하는 이름의 정의가 필요하다. 


 파이썬

 def foo(*args):

    return tuple(*args)

 ...

 triple = foo(5, 6, 7)

 C++

 template <typename... T> auto foo(T&&... args) {

    return std::make_tuple(args...);

 }

 ...

 auto triple = foo(5, 6, 7);


'개발 > C++' 카테고리의 다른 글

프로그래밍언어] LEX와 YACC  (0) 2014.12.09
32bit dll mfc100u msvcp100 msvcr100  (0) 2014.12.01
visual studio 2010 release mode 컴파일  (0) 2014.11.04