모두의 코드 커뮤니티

9.1 함수 템플릿 관련 질문이 있습니다

#include <iostream>

template <typename T>
class Vector {
	T* data;
	int capacity;
	int length;

public:
	
	typedef T value_type;
	
	Vector(int n = 1) : data(new T[n]), capacity(n), length(0) {}

	void push_back(T s) {
		if (capacity <= length) {
			T* temp = new T[capacity * 2];
			for (int i = 0; i < length; i++) {
				temp[i] = data[i];
			}
			delete[] data;
			data = temp;
			capacity *= 2;
		}

		data[length] = s;
		length++;
	}
	
	T operator[](int i) { return data[i]; }

	void remove(int x) {
		for (int i = x + 1; i < length; i++) {
			data[i - 1] = data[i];
		}
		length--;
	}
	int size() { return length; }
	void swap(int i, int j) {
		T temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}
	~Vector() {
		if (data) {
			delete[] data;
		}
	}
};
template <typename Cont>
bool compare(Cont& cont,Cont& cont2) { 
//인자로 Cont& 하면은 안되고 Cont 나 const Cont& 나 Cont&& 는 왜 되는 건지 궁금합니다.
	return cont > cont2;
}
template <typename Cont>
void bubble_sort(Cont& cont) {
	for (int i = 0; i < cont.size(); i++) {
		for (int j = i + 1; j < cont.size(); j++) {
				if(!compare(cont[i], cont[j])){
					cont.swap(i, j);
			}
		}
	}
}
int main() {
	Vector<int> int_vec;
	int_vec.push_back(3);
	int_vec.push_back(1);
	int_vec.push_back(2);
	int_vec.push_back(8);
	int_vec.push_back(5);
	int_vec.push_back(3);

	std::cout << "befor sort ---- " << std::endl;
	for (int i = 0; i < int_vec.size(); i++) {
		std::cout << int_vec[i] << " ";
	}

	std::cout << std::endl << "after sort ---- " << std::endl;
	bubble_sort(int_vec);

	for (int i = 0; i < int_vec.size(); i++) {
		std::cout << int_vec[i] << " ";
	}
	std::cout << std::endl;
}

template
bool compare(Cont& cont,Cont& cont2) {
return cont > cont2;
}

9.1강의를 보던중 compare 함수를 내가 따로 작성해도 될까 싶어 작성해 봤습니다.
허나, compare 함수의 인자를 Cont&로 하니

|오류|C2664|‘bool compare(Cont &,Cont &)’: 인수 1을(를) 'T’에서 ‘Cont &’(으)로 변환할 수 없습니다.

라는 오류를 뿜어냈습니다.

도저히 이해가 안갑니다…

제가 생각 하기로는,

int sum(int& x,int& y) {
	return x + y;
}
int main() {
	int b = 3;
	int& a = b;
	int& c = a;
	std::cout << sum(a, c) << std::endl;  // 6 출력.
	return 0;
}

위의 코드를 실행 하게 되면, int&(레퍼런스 형)을 인자로 받는 sum 함수는 a( int& 타입) 과
c (int & 타입)을 파라미터로 주게 되더라도 작동이 되는걸 확인 할 수 있습니다.

sum(int& x , int& y) 에서 int& x 는 단지 int& a 의 다른 별명을 선언해주는거 뿐 아닌가요?

쓰다 보니 질문이 명확하지 않은거 같습니다…

정리해서 말씀 드리자면,

template
bool compare(Cont& cont,Cont& cont2) {
위 함수에서 인자로 Cont& 하면은 안되고 Cont 나 const Cont& 나 Cont&& 는 되는 이유가 궁금합니다.

좋아요 1

좋은 질문이네요.

일단 compare 를 쓰는 부분을 보면

compare(cont[i], cont[j])

이렇게 하고 있죠. 그럼 [] 가 무슨 타입을 리턴하는지 보면

	T operator[](int i) { return data[i]; }

위 처럼 그냥 레퍼런스가 아니라 그냥 값인 T 타입을 리턴하고 있습니다. 쉽게 말해

int func() { return 3;}

과 다를게 없다는 것입니다.

암튼 이 operator[]우측값 을 리턴합니다. 왜냐하면

int i = data[3]; // 가능
data[3] = 4; // 불가능

이기 때문이죠. 이는 위의 func 이

int i =func(); // 가능
func() = 4; // 불가능

인 것과 같은 맥락입니다. 나중에 배우시겠지만 우측값은 우측값 레퍼런스나 상수 레퍼런스만 참조할 수 있기 때문에, const T& 나 T&& 밖에 불가능하지요.

이를 고치기 위해서는 operator[] 가 우측값을 리턴하지 않게 T& operator[](int i) 로 바꾸는 것입니다. 이러면 operator[] 가 좌측값을 리턴하게 할 수 있습니다. 사실 [] 의 용법을 생각하면 이렇게 고치는 것이 맞습니다.

좋아요 1

감사합니다 선생님.
바로 이해가 되었습니다!