VC6 에서 std::list::sort() 사용

litnsio2의 이미지

VC 로 작업하다 생긴 문제점을 질문해도 될런지 모르겠군요.
list 를 소트하려고 하는데 VC6 으로는 문제가 이만저만이 아니군요.
알아보니 VC6에선 STL 표준이 확립되기 전에 지들맘대로 만들어놔서 그렇다던데..
암튼.. 문제점을 요약하자면, 두개의 클래스가 있습니다.

clas person {
   string name;
   string email;
    ...
};
class student : public person {
   string addres;
   ...
};
typedef std::list<student> studentlist;

studentlist 에 저장된 student 객체를 정렬하려는데 부모클래스(person)의 name 멤버를 기준으로 정렬하려고 합니다. 상황에 따라 email 이나 address 와 같이 다른 멤버로 정렬을 해야하구요.

일단 algorithm 에 있는 sort 를 사용하니까 안되더군요. 당연한거였습니다.
list 에 따로 list 만의 sort가 있었으니까요.
(Effective STL 을 보면 std::sort() 함수만으로 리스트를 정렬시키는
편법이 나와있습니다만, 저는 std::list::sort() 함수를 사용하기로 했습니다.
오기가 나서 그런지.. 이걸로 꼭 해결해야겠다는 마음이..+_+ )

list::sort() 를 사용하는데 두가지 버전이 있더군요. list::sort() 와 list::sort(Compreobj) 였습니다.

전자는 리스트 속에 들어간 객체의 operator< 함수를 사용해서 앞뒤를 가려 정렬하는 것이고 후자는 비교객체를 이용하는 것이라는건 알고계시죠.?

일단 후자의 방법을 사용하기로 하고 다음과 같은 함수를 정의하였습니다.
(펑크터로 사용하기 위해서)

bool comparestudentname(student s1, student s2)
{
   return s1.getname() < s2.getname();
}

하지만 VC6 요녀석이 에러를 내더군요.

Quote:

e:\my documents\program source files\vc++ source files\잡다한거\term_2\datamanager.cpp(79) : error C2664: 'void __thiscall std::list<class Student,class std::allocator<class Student> >::sort(struct std::greater<class Student>)' : cannot convert para
meter 1 from 'bool (class Student,class Student)' to 'struct std::greater<class Student>'
No constructor could take the source type, or constructor overload resolution was ambiguou

그말인즉슨, 펑크터를 사용할수 없다는 말인것 같았습니다. VC6 자신은 std::greater<Student> 를 사용하겠다 이거죠.. 글고 전달된 함수객체가
std::greater<Student> 로 변환이 불가능하다.. 그래서 못한다...

지리즈의 이미지

STL대신 ATL을 사용하세요.

There is no spoon. Neo from the Matrix 1999.

BL의 이미지

litnsio2 wrote:
bool comparestudentname(student s1, student s2)
{
   return s1.getname() < s2.getname();
}

functor가 아니고 comparestudentname 함수 포인터 넣은것 아닌가요?
Effective STL 보시는것 같으니 더 설명할 필요는 없겠죠. :)

exsider의 이미지

그건 VC++6 가 표준을 제대로 지원하지 못하기 때문일 겁니다.
std::list::sort(op)를 표준대로 구현하려면 멤버함수 템플릿을 써야하는데 VC++6는 이를 지원하지 않습니다. 그래서 op의 타입을 std::greater<T>로 고정시켜 구현하는 편법을 쓴 것 같습니다.
현재 가능한 방법은 std::greater<Student>를 직접만드는 것입니다. (그리 좋은 방법은 아닙니다.) 또는 리스트의 원소를 벡터에 복사한 후 벡터에 sort알고리즘을 적용하면 될 겁니다.
(복사할 때 std::vector<Student> vec(list.begin(), list.end()) 로 해보세요. 에러가 날 껍니다. (위와 같은 이유) )

yielding의 이미지

vc 7.1, gcc3.x 로 테스트 했습니다. (버전6은 테스트 못해봤어요..)

#include "stdafx.h"

#include <list>
#include <string>
#include <cstring>
#include <iostream>

using namespace std;

struct student{ 
    string name; 
    string email; 
    string addres; 
    bool operator<(const student& other) {
        return strcmp(this->name.c_str(), other.name.c_str()) < 0;
    }
}; 

typedef std::list<student> studentlist; 

int main()
{ 
    student a, b, c;
    studentlist l;

    a.name = "c11"; l.push_back(a);
    b.name = "a2", l.push_back(b);
    c.name = "b3"; l.push_back(c);
    l.sort();

    for (studentlist::iterator it=l.begin(); it != l.end(); ++it) {
        cout << it->name << endl;
    }
    return 0;
}

Life rushes on, we are distracted

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.