• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

컴파일에러

21.08.30 20:44 작성 조회수 154

0

main문에 강의상 shuffle하기 위한 그 컴파일 방식?이 컴파일러가 c++17 이후라서 저렇게 추가했는데요!

#include <iostream>

#include <vector>

#include <algorithm>

#include <random>

using namespace std;

class Cents{

private:

    int m_cents;

public:

    Cents(const int &cents):m_cents(cents){}

    int& getCents() { return m_cents; }

    int getCents() const { return m_cents; }

    friend std::ostream& operator << (std::ostream &out,const Cents &cents){

        out<<cents.m_cents;

        return out;

    }

    friend bool operator > (const Cents&c1, const Cents&c2){

        return c1.m_cents > c2.m_cents;

    } //std::sort쓸때는 >를 해야지 <를 하면안됨

};

int main(int argc, const char * argv[]) {

    std::random_device rd;

    std::mt19937 g(rd());

    vector<Cents>arr(20); //arr이름으로 된 Cents형 20개

    for(unsigned i = 0 ; i<20 ; ++i){

        arr[i].getCents() = i; //getCents의 반환형이 참조형이 되야함을 기억할 것!

        //함수 리턴값은 R-value 입니다. int a = 3; 이라는 식이 있을 때 바로 여기서 3이 R-value 라는 것을 앞에서 배우셨을 겁니다. R-value 메모리는 임시 객체이며 개발자가 임의로 수정할 수 없습니다. 함수 리턴값에 대입을 하고 싶다면 L-value 로서 리턴될 수 있도록 getCetns 의 리턴형을 int & 로 바꿔주세요.

    }

    std::shuffle(begin(arr),end(arr),g);

    

    for(auto &e : arr){

        cout<<e<<" ";

    }cout<<endl;

    

    std::sort(begin(arr),end(arr)); //sort는 크기 비교하는 거라서 >나 <가 필요한데 > 필요하다.

    for(auto &e : arr){

        cout<<e<<" ";

    }cout<<endl;

    

    return 0;

}

오류내용:

답변 1

답변을 작성해보세요.

0

안소님의 프로필

안소

2021.08.31

안녕하세요!

1. Cents 기본 생성자 없다는 에러

에러 메세지가 말해주는 그대로 기본 생성자 추가해주시면 됩니다.

vector<Cents> arr(20); 이건 Cents 객체를 20개 넣어둔 상태에서 시작하는거나 마찬가지에요. 원소 20개가 들어갈 수 있는 벡터를 선언해놓았다는건 그만큼의 메모리를 확보해두었다는 것입니다. 확보해두었다는 의미는 그 메모리에 원소들이 들어가있다는 의미입니다. 자리를 차지하고 있는거니까요! 그렇기에 Cents 객체 20개가 차지하고 있는 상태로 시작하는거에요! vector<int> arr(3); 이라면 3 사이즈의 벡터가 선언되고 3 개의 int 메모리가 미리 생성되고 자리를 차지합니다. (값은 0 으로 vector가 알아서 초기화해줘요) 사이즈 지정 안하고 그냥 vector<Cents> arr; 로만 선언했다면 이건 아무 메모리 크기가 없는 비어있는 상태 맞습니다.

아무튼 위와 같은 이유로 Cents 객체 20개를 알아서 만들어주려는데 기본 생성자가 없기에 추가해달라고 하는 것입니다. 앞에서 배우셨다시피 생성자 호출을 코드로 직접 작성 안하면, 객체 생성이 필요할 때 디폴트 생성자를 자동으로 호출하도록 컴파일러가 해줍니다. 단, 질문자님 코드처럼 파라미터가 있는 다른 생성자들이 이미 정의가 되어있다 하면 자동으로 디폴트 생성자 안해줘요! 직접 정의하라고 에러냅니다.

2. sort 에러

sort(begin(arr), end(arr)) 이렇게 쓰시면 안되고 sort(arr.begin(), arr.end()) 이렇게 쓰셔야해요. 

khb4435님의 프로필

khb4435

질문자

2021.08.31

감사합니다 말씀해주신 부분은 생성자에 =0하는 방식으로 오류를 피할 수 있었습니다!

다만 두번 째 오류에 대해서 제가 찾아본 결과

Invalid operands to binary expression ('const Cents' and 'const Cents')

스택오버플로우보니, const Cents끼리 비교하는 연산자가 유효하지 않다라는 건데, 보통 operator연산자를 수정,추가하는 방식으로 해결하던데 저는 bool operator > 함수가 제대로 된 것 같아서 이유를 잘 모르겠습니다.

도와주시면 감사하겠습니다.

#include <iostream>

#include <vector>

#include <algorithm>

#include <random>

using namespace std;

class Cents{

private:

    int m_cents;

public:

    Cents(const int &cents=0):m_cents(cents){}

    int& getCents() { return m_cents; }

    int getCents() const { return m_cents; }

    friend std::ostream& operator << (std::ostream &out,const Cents &cents){

        out<<cents.m_cents;

        return out;

    }

    friend bool operator > (const Cents&c1, const Cents&c2){

        return c1.m_cents > c2.m_cents;

    } //std::sort쓸때는 >를 해야지 <를 하면안됨

};

int main(int argc, const char * argv[]) {

    std::random_device rd;

    std::mt19937 g(rd());

    vector<Cents>arr(20); //arr이름으로 된 Cents형 객체 20개 //중요. 이건 메모리가 할당된 상태임. 즉 객체가 만들어진 상태. 그래서 생성자에 =0을 추가함.

    for(unsigned i = 0 ; i<20 ; ++i){

        arr[i].getCents() = i; //getCents의 반환형이 참조형이 되야함을 기억할 것!

        //함수 리턴값은 R-value 입니다. int a = 3; 이라는 식이 있을 때 바로 여기서 3이 R-value 라는 것을 앞에서 배우셨을 겁니다. R-value 메모리는 임시 객체이며 개발자가 임의로 수정할 수 없습니다. 함수 리턴값에 대입을 하고 싶다면 L-value 로서 리턴될 수 있도록 getCetns 의 리턴형을 int & 로 바꿔주세요.

    }

    std::shuffle(begin(arr),end(arr),g);

    

    for(auto &e : arr){

        cout<<e<<" ";

    }cout<<endl;

    

    std::sort(arr.begin(),arr.end()); //sort는 크기 비교하는 거라서 >나 <가 필요한데 > 필요하다.

    for(auto &e : arr){

        cout<<e<<" ";

    }cout<<endl;

    

    return 0;

}

안소님의 프로필

안소

2021.09.01

비교 연산자 오버로딩시 > 가 아닌 < 로 해야 합니다! 코드 거꾸로 쓰셨어요! > 로 하면 에러가 난다고 강의에서 보여주십니다.

그리고 이건 다른 방법인데 < 비교 연산자 오버로딩 하지 않았더라도

bool compare(const Cent& cent1, const Cent& cent2) {

return cent1.m_cents > cent2.m_cents;

}

이렇게 비교 기준이 될 수 있는 '함수'를 만들어주고 이 함수 포인터를 sort 에 넘겨주는 방법도 있습니다! (tmi 임니다..ㅎㅎ)

sort(arr.begin(), arr.end(), compare)

khb4435님의 프로필

khb4435

질문자

2021.09.01

좋은 tmi 감사드립니다 :)