갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • C++ 소멸자
  • c# delegate
  • 유니티 그래프
  • c# 코루틴
  • 모바일 게임 순위
  • c# Thread
  • 유니티 그래프 그리기
  • 게임 디자인 패턴
  • C# boxing
  • C++
  • 전세계 게임 매출
  • pc 게임 순위
  • 강남 방탈출
  • 유니티 골드그래프
  • C++ virtual
  • 글로벌게임매출
  • 게임 매출 순위
  • C++ 상속
  • c# collection
  • c# coroutine
  • 롤 골드그래프
  • 게임매출순위
  • pc게임 순위
  • 자바
  • 알고리즘
  • Unity Graph
  • c# unboxing
  • 전세계게임매출순위
  • C# 예외 처리
  • 2020년 게임 매출

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

[C++] C언어와 다른 C++ 함수(2)
프로그래밍/C++

[C++] C언어와 다른 C++ 함수(2)

2019. 10. 11. 22:15
728x90
반응형

1. 함수 삭제(delete function)

    - C++ 11부터 추가된 문법

    - 아래 코드의 의미 : int를 인자로 받는 move 함수는 삭제하겠다.

    - 삭제된 함수를 호출하면 컴파일 시간에 오류가 발생한다.

void move(int) = delete; // 함수 삭제

int main() {
    move(10); // 컴파일 에러
}

1.1 함수를 제공하지 않는 것 vs 함수를 삭제 하는 것

    - 함수를 제공하지 않을 경우

        => 함수 호출 시 인자의 암시적 형 변환을 통해서 호출 가능한 함수를 찾게 된다.

        => 데이터 손실이 있을 수 있어 손해

        => 해결 방법은 double 타입의 함수를 만들어 대응

        => 함수를 선언만 제공한다면 함수 호출 시 링크 에러(link error) 발생

    - 함수를 삭제(delete) 할 경우

        => 함수 호출 시 컴파일 에러 발생

  결론 : 함수를 제공하지 않는다고 오류가 나지 않고, 암시적 형 변환으로 데이터 손실이 있을 수 있다. 함수를 삭제할              경우 컴파일 에러가 나므로 확실히 알 수 있다.

int gcd(int a, int b) {
    return b != 0 ? gcd(b, a%b) : a;
}

int main() {
    gcd(2, 10);    // ok
    
    gcd(1.2, 4.8); // gcd(double, double)?
}

    - 암시적 변환에 의한 의도 하지 않은 함수가 호출되는 것을 막기 위해

    - 템플릿이 특정 타입의 함수를 생성하지 못하게 하기 위해

    - 컴파일러가 자동으로 생성하는 멤버함수를 사용하지 못하게(생성하지 못하게) 하기 위해 -> 가장 널리 사용

template<typename T>
T square(T a) {
    return a * b;
}

char square(char) = delete

int main() {
    square(3);   // square(int, int)
    square(3.3); // square(double, double)
    square('a'); // square(char, char) => 함수 삭제를 할 경우 컴파일 에러 발생
}

 


2. trailing return type (후위 반환 타입)

  2.1 함수의 후위 반환 타입 표기법

//int square(int a)
auto square(int a) -> int {
    return a * a;
}

//int main() 
auto main() -> int {
    square(3);
}

     - 함수를 만들 때 사용하는 새로운 표기법

        => 함수의 이름 앞에는 auto를 적고, 괄호 뒤쪽에 -> 반환 타입을 적는 표기법

     - trailing return type 또는 suffix return type

     - C++11 부터 지원

     - 람다 표현식이나 함수 템플릿을 만들 때 주로 사용

 

  2.2 후위 반환 타입 표기법이 필요한 경우

template<typename T1, typename T2>
? add(T1 a, T2 b) {
    return a + b;
}

int main() {
    add(1, 2.3);
}

 

     - 위와 같은 경우에는 ?를 어떻게 적어야 할까?

     - 방법1. decltype(a + b) add(T1 a, T2 b) ?

         => 변수 a와 b가 선언되지 않아 쓸 수 없다. 선언되는 시점은 T1 a지만 사용될 때 a는 선언되지 않은 상태

     - 방법2. auto add(T1 a, T2 b) -> decltype(a + b) ?

         => 컴파일 오류 없음. C++11부터 가능 

         => C++14부터는 -> decltype(a+b)를 지워도 됨. // return에 따라 반환 타입이 결정 됨.

 


3. constexpr function

constexpr int add(int a, int b) {
    return a + b;
}

int main() {
    add(1, 2);
}

  3.1 constexpr 키워드

     - 컴파일 시간의 의미를 가지는 키워드 - C++11

     - 활용1. constexpr 상수 => constexpr int c = 10;

     - 활용2. constexpr function

     - 활용3. if constexpr => if constexpr(c==10) -> 추후 다룰 예정

 

template<typename T, int N>
struct Buffer {
    T data[N];
}

constexpr int add(int a, int b) {
    return a + b;
}

int main() {
    int x = 1;
    int y = 1;
    
    int n1 = add(1, 1); 
    int n2 = add(x, y);  
    
    Buffer<int, 1024> b1;      // ok
    Buffer<int, x> b2;         // error
    Buffer<int, add(1, 2)> b2; // ok
    Buffer<int, add(x, 2)> b2; // error
}

  3.2 constexpr function의 의미

     - 함수의 인자 값을 컴파일 시간에 결정할 수 있으면 컴파일 시간에 함수를 실행

     - 함수의 인자 값을 컴파일 시간에 결정할 수 없으면 실행시간에 함수를 실행

 

  3.3 template parameter

     - 템플릿 인자로 타입 뿐 아니라 정수형 상수도 사용할 수 있다.

     - 모든 템플릿 인자는 컴파일 시간에 결정되어야 한다.

 

#include <iostream>

constexpr int factorial(int n) {
    //
    //
    //
    if(n==1)
        return 1;
    return n * factorial(n-1);
}

int main() {
    int n = factorial(5);
    
    std::cout << n << std::endl;
}

  3.4 constexpr function의 제약

     - factorial 함수 내의 주석처리 된 3줄 부분에 파일을 열 수 있을까? 실행할 때 열어야 할텐데

     - 또, 동적 메모리 할당을 할 수 있을까?

     - C++11에서는 constexpr 함수가 컴파일 시간에 수행되기 위한 제약 조건을 많이 가지고 있었다.

        => return 문장이 한번만 나와야 한다.

     - C++14에서는 대부분 제약이 사라지고 일부 조건만 남아있다.

        => 파일을 오픈 하거나, 동적으로 메모리를 할당 할 수 없다.

        => 가상함수가 될 수 없다.

        => cppreference.com 참고

 


4. lambda expression (람다 표현식)

#include <iostream>

void num(int a) {
    std::cout << "num : " << a << std::endl;
}

int main() {
    num(1); // 함수(함수 인자) - 함수 호출
    
    // 람다 표현식
    [](int a) {
        std::cout << "num : " << a << std::endl;
    }(10);
}

  4.1 람다 표현식의 개념

     - 1. 일반적인 함수 

         => global space에 만들어 놓고 필요할 때 함수의 이름을 사용해서 호출한다.

     - 2. 람다 표현식(lambda expression)

        => 코드 안에서 이름이 없는 함수를 만들어서 사용하는 것

        => 익명의 함수(anonymouse function) , 함수 리터럴(literal)

        => 함수 반환타입과 이름을 제거 하고 [ ]를 표기 한다.

 

#include <iostream>

int add(int a, int b) { return a + b; }

int main() {
    int n1 = add(1, 2);
    
    // 람다표현식 생성, 함수를 만듬, 사용은 안한 상태
    [](int a, int b) { return a + b; };
    
    // 람다표현식으로 생성한 함수를 호출
    int n2 = [](int a, int b) { return a + b; }(1, 2);
}

  4.2 람다 표현식의 모양

     - 일반 함수의 모양에서 반환타입과 함수 이름을 제거하고 []를 표기 한다.

     - [] => lambda introducer  ,  람다 표현식이 시작됨을 나타낸다.

 

#include <iostream>
#include <algorithm>

bool cmp(int a, int b) { return a > b; }

int main() {
    int x[10] = {1, 5, 2, 6, 9, 7, 3, 8, 10, 4};
    
    std::sort(x, x+10);  // 배열의 요소 소팅(시작, 마지막 요소의 다음 주소)
    
    // std::sort(x, x+10, 크기 비교함수); 를 이용해서 큰 수부터 나열로 바꿀 수 있다.
    std::sort(x, x+10, cmp); // 10부터 내림차순으로 정렬
    
    std::sort(x, x+10, 
               [](int a, int b) {return a > b; }); // 위와 같은 문법
    
    for(auto n : x)  // 범위 지정법
        std::cout << n << ", ";
}

  4.3 람다 표현식의 활용

     - sort 함수

        => 배열의 시작 주소와 마지막 다음 주소를 받아서 요소를 퀵소트 알고리즘으로 정렬하는 C++ 표준 함수

        => 3번째 인자로 함수를 전달하면 요소의 비교정책을 변경할 수 있다.

        => <algorithm> 헤더가 필요 하다.

     - 함수가 필요한 곳에 함수 이름 대신 람다 표현식을 사용할 수 있다.

     - 위의 코드에서 cmp함수와 같이 한 번쓰고 말 함수 같은 경우 밖에 선언하기 보다 안에서 한 번 쓰고 말자.

728x90
반응형

'프로그래밍 > C++' 카테고리의 다른 글

[C++] 레퍼런스(reference)  (0) 2019.10.22
[C++] range for / if init / if constexpr  (0) 2019.10.18
[C++] C언어와 다른 C++ 함수(1)  (0) 2019.10.09
[C++] 변수(2)  (0) 2019.10.05
[C++] 변수(1)  (0) 2019.10.05
    '프로그래밍/C++' 카테고리의 다른 글
    • [C++] 레퍼런스(reference)
    • [C++] range for / if init / if constexpr
    • [C++] C언어와 다른 C++ 함수(1)
    • [C++] 변수(2)
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바