C++ 템플릿 함수 짜는데 질문있습니다~
글쓴이: greathero / 작성시간: 일, 2013/03/17 - 3:53오후
int main(int argc, char** argv) { BookWidget bw; doPro(bw); return 0; } template<typename T> void doPro(T& pw) { T pw2(50); T pw3; int a = 10; if(pw.size() > a) { std::cout << "OK" << std::endl; } if(pw != pw2) { std::cout << "OK2" << std::endl; } if(pw != pw3) { std::cout << "ERROR" << std::endl; } else { std::cout << "OK3" << std::endl; } }
위와 같이 템플릿 개념 익힐겸 간단히 짜본 코드가 있습니다.
여기서 보면 연산자 >와 연산자 !=이 있는데요.
이걸 BookWidget.h에 아래와 같이 정의하였습니다.
class BookWidget: public Widget { ... }; bool operator>(const Widget& lhs, const int rhs); // 멤버 함수로 놓지 않고 전역 함수처럼 쓰기 위해 이렇게 했습니다. bool operator!=(const Widget& lhs, const Widget& rhs);
그리고선 BookWidget.cpp에 두개의 연산자에 대한 구현부 코드를 작성했습니다.
그런데, 컴파일을 할 때 doPro 함수에서 "pw.size() > a" <- 이 부분에서 제가 정의한 > 연산자를 자꾸 찾지 못하고 에러를 냅니다.
Namespace안에 연산자 >와 !=을 정의해놓고 using 연산자를 통해서 쓰면 잘 되긴 합니다만...
이렇게 Namespace를 명시하지 않고 전역으로 정의한 연산자를 자연스럽게 쓸 수 있는 방법은 없을까요?
Forums:
주어진 소스 코드만으로는
주어진 소스 코드만으로는 BookWidget::size의 반환 타입을 알 수가 없어 답변드리기 어려울 것 같습니다.
올리시는 질문들을 보면 템플릿에 관한 문제 이전에 아직 C++ 문법에 익숙하지 않으신게 아닌가 싶은데 템플릿없이 클래스를 짜보시는게 더 좋을 것 같습니다.
클래스 템플릿의 연산자에 대해선 클래스 내부에 friend로 선언&정의를 같이 하는 방법이 사용되는데, 이에 대해선 Effective C++ 서적에서 찾아보실 수 있습니다.
이건 클래스 템플릿의 연산자가 아니에요~
일반 클래스의 연산자구요~
단지 일반 클래스를 템플릿 함수에 넘겨서
템플릿 함수에서 연산자를 써먹는 경우에 대해서 말씀 드리는거에요 ㅎㅎ
제 말을 잘못 이해하신거 같네요ㅠ
그리고 size의 반환타입은 Widget* 입니다~
코드가 뭐가 잘못 되었을까요?ㅠ
함수를 템플릿으로 정의해 놓고 연산자는 특정한
함수를 템플릿으로 정의해 놓고 연산자는 특정한 instantiation 에 해당하는 경우만 정의해 놓으면, (네임스페이스를 들락 날락 해야 하는)문제가 생길 수 있습니다.
연산자도 같이 템플릿으로 정의해야 해요.
연산자를 이런식으로 선언해봤는데
이렇게 써봤는데 역시나 컴파일러가 이 연산자들을 찾지를 못하네요ㅠ
클래스에 속해있지도 않고 네임스페이스에도 속해있지 않으면 찾을 방법이 없는건가봐요...
그냥 클래스 내에 unary function처럼
이런식으로 써야 되는걸까요ㅠ
포인터 변수에 대한 specilization 이
일단 오퍼레이터에 대한 이전의 비 템플릿 정의를 헤더에 같이 집어 넣어 컴파일해 보세요.
또는 포인터 변수에 대한 specilization 이 필요할 듯 합니다.
일단 비 템플릿 정의도 같이 넣어 봤는데요ㅠ
헤더파일에 위의 코드를 넣어봤는데 여전히 컴파일러는 > 연산자와 != 연산자의 존재를 모르고있네요ㅠ
"pw.size() > a" <- 이 조건식에서 error C2446: '>' : 'int'에서 'Widget *'(으)로 변환되지 않았습니다. <- 에러가 이렇게 뜨는걸로 봐선...
확실히 연산자의 존재를 컴파일러가 알지 못해서 자꾸 원래의 > 연산자를 사용하려다가 에러가 나는거 같아요...
그리고 이 코드는 객체 타입으로 이터레이터를 넘겨서 쓰는 코드 같은데 갑자기 이런 코드를 왜 써야되는지 잘 이해가 가지 않아요ㅠ
조금 더 쉽게 설명해 주실 수 있을까요?
선언이 아닌 실제 함수 정의를 모두 헤더 파일에 넣고
선언이 아닌 실제 함수 정의를 모두 헤더 파일에 넣고 컴파일해 보시기 바랍니다.
그렇게 해봤는데도 안되네요ㅠㅠ
정말 미스테리네요...
풀소스를 한번 공개해볼테니 혹시라도 미심쩍은거 있으면 알려주세요ㅠ
Widget.h
BookWidget.h
BookWidget.cpp
main.cpp
pw.size()가 반환하는건 Widget*이므로
pw.size()가 반환하는건 Widget*이므로 필요한 건 Widget*과 int를 비교하는 연산자입니다.
아울러
템플릿이 자동으로 없는 연산을 만들어 주지는 않기 때문에,
일반적인 템플릿을 만들고, 원하시는 연산에 대한 Specialization 을 별도로 구현해 주어야 합니다.
그게 이건데요ㅠㅠ
bool operator>(const Widget& lhs, const int rhs) {
return (lhs.getS() > rhs);
}
이거 아닌가요?;
bool operator>(const Widget*
bool operator>(Widget* lhs, const int rhs) {
return (lhs->getS() > rhs);
}
포인터와 레퍼런스를 구분하세요.
포인터와 레퍼런스를 구분하세요.
마지막에 허탈해지네요, 만드신 템플릿은 형식만
마지막에 허탈해지네요,
만드신 템플릿은 형식만 템플릿이 들어가 있지 템플릿이 들어가 있지, 내용은 그냥 함수랑 차이가 없네요.
코드로 보면
이 부분 말씀하시는건가요?
그냥 함수랑 차이가 없다라고 말씀하신게 어떤걸 의미하는지 알려주시면 감사하겠습니다ㅠ
템플릿 암시적 인터페이스에 대해서 실험중이었던지라... 그걸 만족하는지에 대해 보는 코드였거든요
댓글 달기