c++ 구조체를 자료형으로 갖는 list iterator 문제입니다.

ozon1000의 이미지

#include <iostream>
#include <string>
#include <algorithm>
#include <list>
 
using namespace std;
 
struct data
{
	string name;
	int count;
	data(string _name, int _count)
	{
		name = _name;
		count = _count;
	}
};
 
int main()
{
	list<data> a;
	list<data>::iterator it;
	a.push_back(data("a", 1));
	a.push_back(data("b", 2));
	a.push_back(data("c", 3));
 
	it = find(a.begin(), a.end(), "b");
}

코딩이 다음과 같을때..
왜 find 함수가 작동하지 않는건가요??
도와주세요!!
꾸벅___!

shint의 이미지

STL find 에서 구조체 사용하기
찾아보니 find()를 구현한 예제소스가 있네요.

구조체에서 new와 함수를 사용했으니. 좀 무리가 있네요... 오류가 있을 수 도 있으니. 확인해보시기 바랍니다.
검색은 몇번해보니. 됩니다.

댓글 첨부 파일: 

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

ozon1000의 이미지

파일을 다운하고 싶은데 다운이 되지 않네요..

jick의 이미지

find는 == 연산자를 이용해서 원하는 값을 찾습니다. 그러니까 해당 코드가 동작하려면 operator==(const string &) 혹은 operator==(const char *)이 정의되어야 합니다.

그리고 그걸 정의한다고 해도 여전히 개념상의 문제는 남는데...

data("a", 1)과 data("a", 3)이 있다고 하면 이 둘은 모두 "a"와 같은 값을 가지는 것으로 간주하게 됩니다. 그래도 괜찮은가요?

ozon1000의 이미지

operator를 새로 정의해야 하는군요!
그런데 저 코딩 상태 그대로 operator를 정의해도 이상 없나요?

구현하고자 하는 방향을 미루어 볼 때 data("a", 1)과 data("a", 3)은 같다고 간주하면 안될 것 같습니다.
string과 int형 데이터 모두 같아야 할 것 같습니다.

jick의 이미지

주어진 코드에서 operator==를 정의해도 돌기는 돌 것 같습니다만...

find는 "주어진 인자와 *같은* (operator==가 true를 돌려주는) 값을 찾아라"인데 "같다"의 조건을 알기 위해 string, int 두 필드를 다 보아야 한다면 현재 하려고 하는 일과 맞지 않습니다. 말하자면 operator==가 "사람이 예상하는" 동작을 하지 않게 되기 때문에 나중에 매우 헷갈릴 수 있게 됩니다.

그냥 수동으로 for loop 돌려서 비교하는 것을 추천드립니다.

* 코드는 단순한 게 좋아요.

익명 사용자의 이미지

새로운 operator를 정의하지 않고 말씀하신 것처럼 for 문을 사용해 비교했습니다.

struct를 자료형으로 갖는 stl은 여러모로 불편한점이 많음을 깨닳았습니다.

익명 사용자의 이미지

== 연산자 정의 필요합니다

익명 사용자의 이미지

부득이 구조체 이름 data는 Data로 바꿨습니다. C++17부터 std::data가 생기는 바람에 이름이 겹치거든요.
(별도로 언급드리지 않는 한 C++17의 기능을 쓰겠다는 건 아닙니다. 다만 C++17을 지원하는 컴파일러에서 문제가 생기는 걸 예방하는 것입니다.)
또한 생성자에서 멤버변수를 초기화할 때는 아래와 같이 초기화 리스트를 작성하는 편이 효율적입니다. 이는 멤버변수의 디폴트 초기화가 비쌀수록 더더욱 그렇습니다.

일단 언급하신 코드는 find 대신 find_if를 이용하여 간단히 구현할 수 있습니다. 다만 검색 조건을 별도의 함수(cond_function)로 지정해줘야 합니다.

#include <iostream>
#include <string>
#include <algorithm>
#include <list>
 
using namespace std;
 
struct Data
{
	string name;
	int count;
	Data(string name, int count):name(name), count(count){
	}
};
 
bool cond_function(const Data &data) {
	return data.name == "b";
}
 
int main()
{
	list<Data> a;
	list<Data>::iterator it;
	a.push_back(Data("a", 1));
	a.push_back(Data("b", 2));
	a.push_back(Data("c", 3));
 
	it = find_if(a.begin(), a.end(), cond_function);
}

아래와 같이 함수 객체를 이용할 수도 있습니다.

#include <iostream>
#include <string>
#include <algorithm>
#include <list>
#include <functional>
 
using namespace std;
 
struct Data
{
	string name;
	int count;
	Data(string name, int count) :name(name), count(count) {
	}
};
 
class CondObject : public unary_function<Data, bool> {
public:
	bool inline operator()(const Data &data) const{
		return data.name == "b";
	}
};
 
int main()
{
	list<Data> a;
	list<Data>::iterator it;
	a.push_back(Data("a", 1));
	a.push_back(Data("b", 2));
	a.push_back(Data("c", 3));
 
	it = find_if(a.begin(), a.end(), CondObject());
}

함수 객체를 쓰는 방법의 장점은, 찾을 값이 문자열 상수가 아닐 때에도 유연하게 동작하게 만들 수 있다는 점이죠. 아래 코드를 보세요.

#include <iostream>
#include <string>
#include <algorithm>
#include <list>
#include <functional>
 
using namespace std;
 
struct Data
{
	string name;
	int count;
	Data(string name, int count) :name(name), count(count) {
	}
};
 
class CondObject : public binary_function<Data, string, bool> {
public:
	bool inline operator()(const Data &data, const string &s) const{
		return data.name == s;
	}
};
 
int main()
{
	list<Data> a;
	list<Data>::iterator it;
	a.push_back(Data("a", 1));
	a.push_back(Data("b", 2));
	a.push_back(Data("c", 3));
 
	it = find_if(a.begin(), a.end(), bind2nd(CondObject(), "b"));
	it = find_if(a.begin(), a.end(), bind2nd(CondObject(), "c"));
}

C++11을 쓰기 시작하면 코드가 좀 더 간단해집니다. binary_function 같은 건 치우고, bind2nd보다 유연한 bind의 힘을 빌립시다. 그냥 함수(cond_function)를 쓸 수도 있고 함수 객체를 쓸 수도 있습니다.

#include <iostream>
#include <string>
#include <algorithm>
#include <list>
#include <functional>
 
using namespace std;
 
struct Data
{
	string name;
	int count;
	Data(string name, int count) :name(name), count(count) {
	}
};
 
bool cond_function(const Data &data, const string &s) {
	return data.name == s;
}
 
class CondObject{
public:
	bool inline operator()(const Data &data, const string &s) const {
		return data.name == s;
	}
};
 
int main()
{
	list<Data> a;
	list<Data>::iterator it;
	a.push_back(Data("a", 1));
	a.push_back(Data("b", 2));
	a.push_back(Data("c", 3));
 
	using namespace std::placeholders;
	it = find_if(a.begin(), a.end(), bind(cond_function, _1, "b"));
	it = find_if(a.begin(), a.end(), bind(CondObject (), _1, "b"));
}

물론 이왕 C++11을 쓰는 김에, 코드에 쓸데없이 주렁주렁 달리는 cond_function이나 CondObject 같은 걸 치워 버리고 더 깔끔하게 만들 방법도 있습니다. Predicate가 필요한 STL 함수를 자주 써야 할 경우에 편리한 방법이죠.

#include <iostream>
#include <string>
#include <algorithm>
#include <list>
 
using namespace std;
 
struct Data
{
	string name;
	int count;
	Data(string name, int count) :name(name), count(count) {
	}
};
 
int main()
{
	list<Data> a;
	list<Data>::iterator it;
	a.push_back(Data("a", 1));
	a.push_back(Data("b", 2));
	a.push_back(Data("c", 3));
 
	it = find_if(a.begin(), a.end(), [](const Data &data) {return data.name == "b";});
}

검색 문자열을 바꿔가며 쓰고 싶으면 이렇게 하면 되겠죠.

#include <iostream>
#include <string>
#include <algorithm>
#include <list>
 
using namespace std;
 
struct Data
{
	string name;
	int count;
	Data(string name, int count) :name(name), count(count) {
	}
};
 
int main()
{
	list<Data> a;
	list<Data>::iterator it;
	a.push_back(Data("a", 1));
	a.push_back(Data("b", 2));
	a.push_back(Data("c", 3));
 
	string s = "b";
	it = find_if(a.begin(), a.end(), [&s](const Data &data) {return data.name == s;});
}

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.