[완료] c++ template 함수에 iterator를 넘겨줄때...

login321의 이미지

처음에
vector< int> src를 vector< int> dst에 복사하고 이를 출력하는 함수(함수명:copy)를 만들었습니다.

#include <iostream>
#include <vector>
 
using namespace std;
 
void copy(vector<int>::iterator b, vector<int>::iterator e) {
  // b == src.begin()
  // e == src.end();
 
  // copy src to dst
  vector<int> dst;
  for (vector<int>::iterator i = b; i != e; ++i)
    dst.push_back(*i);
 
  // print dst
  for (vector<int>::iterator i = dst.begin(); i != dst.end(); ++i)
    cout << *i << endl;
}
 
int main() {
  vector<int> src(2);
  src[0] = 10;
  src[1] = 20;
 
  copy(src.begin(), src.end());
  return 0;
}

의도했던 대로 잘 됩니다.

그런데
int뿐만 아니라 double, float일때도 사용할 수 있게 template으로 변경했어요.(int를 T로 치환)

template <typename T>
void copy(typename vector<T>::iterator b, typename vector<T>::iterator e) {
  // b == src.begin()
  // e == src.end();
 
  // copy src to dst
  vector<T> dst;
  for (typename vector<T>::iterator i = b; i != e; ++i)
    dst.push_back(*i);
 
  // print dst
  for (typename vector<T>::iterator i = dst.begin(); i != dst.end(); ++i)
    cout << *i << endl;
}


copy(src.begin(), src.end()); 이렇게 함수콜을 하면 함수매칭이 안된다고 하네요.

error: no matching function for call to 'copy(std::vector<int>::iterator, std::vector<int>::iterator)

제눈엔 아무리 뜯어봐도 함수명 같고, 파라미터 리스트도 같은데 함수매칭이 안된다고 하니 답답할 노릇입니다. 고수님들의 고견 부탁드립니다.

사족: 결국 void copy(typename vector::iterator b, typename vector::iterator e) {
대신 void copy(T b, T e) {
이렇게 iterator를 통째로 T로 두는 걸로 해결은 했는데
처음 시도했던 방법은 왜 에러가 나는지 도무지 이해가 안되어 잠이 오질 안습니다!

익명 사용자의 이미지

처음 소스를...

int main() {
  vector<int> src(2);
  src[0] = 10;
  src[1] = 20;
 
  copy<int>(src.begin(), src.end());
  return 0;
}

라고 하면 잘 될겁니다.

이제 왜 안되는지 보이죠?

yielding의 이미지

제 생각에 질문하신 요지가 c++의 template function이 type deduction을 하기 때문에 copy<int>(...)라고 하지 않아도 컴파일러가 알아서 typename vector<T>::iterator 의 T를 int로 알아내야 하는것 아니냐는 것같은데 맞나요?

typename Q<T>::X같은 qualified type name은 컴파일러가 T의 타입을 deduction하지 못합니다.
마찬가지로 nontype expression, 예를 들면 V<I+1>에서 I, 을 deduction할 수 없습니다.

Life rushes on, we are distracted

winner의 이미지

우선 마지막에 작성하신 것이 일반적인 copy 구현이니까 그게 추천되는 방식입니다.
만일 vector의 iterator로 copy의 사용을 한정하고 싶다면 template을 이용해서 좀 돌아가면 가능합니다.
STL의 iterator_category 가 구현되는 형태로 작업하시면 가능한데 작업량이 좀 많아서 별로 추천하고 싶지는 않네요.
그리고 사실 최종 결과물도 맘에 안 드실테고요.

login321의 이미지

답변 너무 감사합니다. < int> 하나 붙여주니 잘돌아갑니다.
c++ 기본서를 보면서 template부분 공부하고 있었는데 여기엔 기본적인 사용법만 있고
iterator를 이용한 template이나 type deduction같은 내용이 없어서 이유를 못찾고 있었네요.
yielding님 말씀대로 이렇게하면 되겠지 해서 나온 코드입니다.
template만을 다룬 책이 있을정도니 c++은 알아야할게 좀 많네요...

무변이의 이미지

아주 먼 옛날의 질문에 제가 답글을 . . . .
저도 오늘 비슷한 문제를 가지고 인강으로 배우는 중인데 강의 내용이 무슨 내용인지 몰라서 검색중에
이 질문글을 읽다가 언뜻 스쳐가는 것이 있어서 만들어 본 것입니다.

#include
#include
#include
using namespace std;

template
void copy(typename vector& vec, string msg) { typename vector::iterator iter; vector dst; // 복사받을 벡터 for (iter=vec.begin();iter != vec.end();iter++) //벡터복사 dst.push_back(*iter);

cout << “ “ << msg <<” = {”; for (iter = dst.begin(); iter != dst.end(); iter++) { cout << *iter << “, “; } cout << “\b\b} “ << endl; }

int main() { vector src1 = { 1,2,3,5 }; src10 = 10; src11 = 20; src1.push_back(43);

copy(src1, “src1”); cout << endl; vector src2(3); src20 = 1.45; src21 = 3.92; src22 = 11.2; copy(src2, “src2”); return 0; }
무변이의 이미지

// 범위기반 for문으로 출력하려면 아래의 내용을
// 사용하여 출력할 수 있습니다.
cout << " " << msg << " = {";
for (T& tt: dst) {
cout << tt << ", ";
}
cout << "\b\b} " << endl;

무변이의 이미지

// find02.cpp

#include
#include
#include
using namespace std;

template
void copy(typename vector& vec, string msg) {
typename vector::iterator iter;
vector dst; // 복사받을 벡터
for (iter=vec.begin();iter != vec.end();iter++) //벡터복사
dst.push_back(*iter);

//반복자를 이용한 출력
cout << " " << msg <<" = {";
for (iter = dst.begin(); iter != dst.end(); iter++) {
cout << *iter << ", ";
}
cout << "\b\b} " << endl;

//범위기반 for문을 이용한 출력
cout << " " << msg << " = {";
for (T& tt: dst) {
cout << tt << ", ";
}
cout << "\b\b} " << endl;

}

int main() {
vector src1 = { 1,2,3,5 };
src1[0] = 10;
src1[1] = 20;
src1.push_back(43);

copy(src1, "src1");

cout << endl;

vector src2(3);
src2[0] = 1.45;
src2[1] = 3.92;
src2[2] = 11.2;
copy(src2, "src2");

return 0;
}

무변이의 이미지

// find02.cpp 
 
#include <iostream>
#include <vector>
#include <string>
using namespace std;
 
template <typename T>
void copy(typename vector<T>& vec, string msg) {
    typename vector<T>::iterator iter;
    vector<T> dst; // 복사받을 벡터
    for (iter=vec.begin();iter != vec.end();iter++) //벡터복사
        dst.push_back(*iter);
 
    //반복자를 이용한 출력
    cout << " " << msg <<" = {";
    for (iter = dst.begin(); iter != dst.end(); iter++) {
        cout << *iter << ", ";
    }
    cout << "\b\b} " << endl;
 
    //범위기반 for문을 이용한 출력
    cout << " " << msg << " = {";
    for (T& tt: dst) {
        cout << tt << ", ";
    }
    cout << "\b\b} " << endl;
 
}
 
int main() {
    vector<int> src1 = { 1,2,3,5 };
    src1[0] = 10;
    src1[1] = 20;
    src1.push_back(43);
 
    copy(src1, "src1");
 
    cout << endl;
 
    vector<double> src2(3);
    src2[0] = 1.45;
    src2[1] = 3.92;
    src2[2] = 11.2;
    copy(src2, "src2");
 
    return 0;
}
무변이의 이미지

.

무변이의 이미지

template 를 해야하는데 template만 보이네요.

김정균의 이미지

로그인 하시고 작성 하시면, 수정이 가능 합니다.
코드는 코드 블럭을 사용해서 작성 하시면 됩니다.

글 작성 하실 때, textarea 에 해당 내용을 안내하고 있습니다.

댓글 달기

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