• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:テンプレートについて)

テンプレートについて - テンプレート関数のコンパイルエラーと要約

alfeimの回答

  • alfeim
  • ベストアンサー率58% (114/195)
回答No.1

T::iteratorが出来ない理由ですが もし、templateにintなどのプリミティブタイプが渡された場合、 T::iteratorはどう解釈されるか考えてみてください たとえばintを渡した場合、T::iteratorはint::iteratorとおきかえられて解釈されます そのコードの前迄にint::iteratorが宣言されてなければ使えませんよね? (iteratorはC++の言語仕様ではなくSTLで実装されたものでありtypedefで置き換えられたポインタである事が多いようです) また、T::iteratorという表記ではTから置き換えられるnamespaceまたはTから置き換えられるクラス内の物でなければなりません さらにC++コンパイラでは  T::iterator p; という式は変数、またはクラス宣言として受け取られるためT::iteratorはクラス、またはプリミティブタイプでなければ構文的に不正なものとなってしまいます という訳でT::iterator以前に同じクラススコープ、またはnamespaceになる場所でtypedefでiteratorを宣言してやる必要があります あ、あと内部でiteratorを使うのだからそのクラス内でbegin(),end()なども実装してやる必要があるでしょう

nagata
質問者

補足

>という訳でT::iterator以前に同じクラススコープ、またはnamespaceになる場所でtypedefでiteratorを宣言してやる必要があります つまりどういうことでしょう? Tに渡すクラスの定義の中でiteratorを定義すればいいのでしょうか? 試しに次のようなクラスを作りましたがだめでした。 class Array10 { public: typedef int* iterator; int table[11]; iterator begin(){return table;} iterator end(){return table+10;} }; ちなみにmainは次のように書きました。 main() { Array10 a; for(int i=0;i<10;i++)a.table[i]=i; printAll(a); } printAllのなかで T::iterator が Array10::iterator に置き換わっているなら動きそうなものですが。 それともprintAllのなかでT::iteratorを使う前にtypedefで宣言する必要があると言うことでしょうか。 しかしTがなにか分かるまでtypedefできないと思うのですが。つぎのような感じでしょうか。 template<class T> void printAll(T t) { typedef ??? T::iterator; T::iterator p; for(p=t.begin();p!=t.end();p++)cout<<*P; cout<<endl; }

関連するQ&A

  • テンプレート関数

    template<typename Iterator, typename Type> void show(Iterator start, Iterator end) { ostream_iterator<Type> oi(cout, " "); copy(start, end, oi); } のように、関数の引数の型の数 (Iterator:1個)より、 テンプレートの数(Iterator,Type: 2個)が上回ってしまう場合、 この関数をどのように呼び出せばいいのでしょうか? 例えば、 vector<int> v; show(v.begin(), v.end()); ではエラーになります。

  • テンプレートクラスとSTLを利用したMyListクラス

    こんにちは。STLのリストを使い自分だけのMyListクラスを作ろうとしたのですが、コンパイルできません。 エラーメッセージは警告 std::list<T>::iterator' : 依存名は型ではありません。 とでます。 ご教授お願いします。 #include<list> #include<iterator> template <class T> class CMyList { public: CMyList(); //virtual ~CMyList(); //bool HasNext(); //T Next(); //void Pushback( T t ); //void EraseCheck(); //T GetFirst(); private: std::list< T > m_List; std::list< T >::iterator m_It;//コンパイルエラー }; template <class T> CMyList<T>::CMyList() { m_List.clear(); std::list< T > ::iterator it = m_List.begin();//こう宣言する分にはOK m_It = m_List.begin(); } int main() { CMyList<int> m_List; return 0; }

  • テンプレートを使用した時のbcc32とclの違い

    c++を勉強していてわからない事があり、質問させていただきたいと思います。 c++でテンプレートを使ったクラスを以下のように作りました。 //test.h template <class T> class Test { public: Test(); T m_X; }; template <class T> Test<T>::Test<T>() //<<<実際のファイルではここが10行目です { m_X = 10; } //test.cpp #include <iostream.h> #include "Test.h" void main() { Test<int> t; cout << t.m_X << endl; } これをVC++6.0のコンパイラclでは問題なくコンパイルできるのですが、Borland C++ Compailerのbcc32でコンパイルすると、「エラー E2040 Test.h 10: 宣言が正しく終了していない」とのエラーメッセージがでます。なぜ、clでは問題なくコンパイルできるのにbcc32ではコンパイルできないのでしょうか。 ご存知の方、教えていただけないでしょうか。よろしくお願いします。

  • listをvectorにコピーするときに

    例えば #include<iostream> #include<vector> #include<list> using namespace std; void main(void) { unsigned pos; list<unsigned> lu; list<unsigned>::iterator p; vector<unsigned> vu; for(lu.clear(),pos=0;pos<9;lu.push_back(pos++)); for(p=lu.begin();p!=lu.end();cout<<*p++); cout<<endl; vu=vector(lu); //error for(pos=0;pos<vu.size();cout<<vu[pos++]); cout<<endl; } とするとエラーになるため//errorのかわりに vu.clear(); vu.insert(vu.begin(),lu.begin(),lu.end()); としていますが少し不細工です 他に方法はあるのでしょうか?

  • c++テンプレート関数名

    #include <iostream> #include <string> using namespace std; template <class T> T maxdt std(T a,T b){ if (a>b) return a;else return b; } int main (){ int id1,id2,n1 = 1000,n2 = 2000; double ddt; string sdt,s1 = "abcd",s2 = "jklm"; id1 = maxdt(n1,n2); id2 = maxdt(3000,4000); ddt =maxdt (55.55,66.66); sdt = maxdt(s1,s2); cout << "id1" << id1 <<endl; cout << "id2" << id2 <<endl; cout << "ddt" << ddt <<endl; cout << "sdt" << sdt <<endl; return 0; } というプログラムが例題であり、僕は横着をしてmaxdtをmaxという名前としてプログラムを作ったところ、 オーバーロード関数の呼び出しがあいまいです。 というエラーが表示されコンパイルできませんでした。 環境はubuntu 12.04,gcc 4.6.3 g++でコンパイルしました。 ググってもテンプレート関数の名前の付け方に規則は存在していないようなのですが、 これは直前に作ったプログラムの影響でしょうか?(maxという関数を作っていたので) それとも別の規則が存在したりするのでしょうか?

  • Pascalへの変換について

    C言語のプログラムをPascalに変更してほしいのですが 分かりません。 #include<iostream> #include<list> #include<utility> #include<algorithm> void output(const std::pair<char,int>&p){ std::cout << "入力文字'"<< p.first << "' 入力回数 "<< p.second << std::endl; } int main(){ typedef std::list<std::pair<char,int> >list_t; list_t count; for(char c;std::cin.get(c) && c != '.';){ if(c == '\n')continue; list_t::iterator it = count.begin(),end=count.end(); for(;it != end;++it) if(it->first == c)break; if(it == end){ count.push_back(std::make_pair(c,0)); it = count.end(); --it; } ++it->second; } std::for_each(count.begin(),count.end(),output); } よろしくお願いします

  • C++テンプレートでの引数

     こんにちは。 今回は、C++ テンプレートで引数に構造体を使えないか悩んでいます。 例えば #include <stdio.h> typedef struct _rect{ int x; int y; }RECT; typedef struct _rect{ double x; double y; }DATA; template <calss T> T Function(T abc) { // 構造体の要素にも対応している。 cout << abc//の要素x << endl; cout << abc//の要素y << endl; return T; } int main() { RECT t; DATA r; t.x = 80; t.y = 90; t = Function(t); // こういった事をしたい r = Function(r); return 0; } というふうにしたいんです。 テンプレート関数に引数として構造体にしてそれぞれの要素を参照する場合はどうすれば よろしいのか教えてください。 よろしくお願いします。

  • C++のtemplateクラス前方宣言について教えてください

    C++で、以下のようなコードを書いたのですがコンパイルが通りません。 どのようにコードを修正すればコンパイルを通すことができるでしょうか??教えてください。 template <class _T> class Test; // 上をclass Test<_T>にしてもコンパイルは通りません void main() {   Test<int> hoge; } template <class _T> class Test { public:   _T val;   Test():val(0){}; }; /*! エラー内容: 前方宣言class Test;の場合 'hoge'が未定義のclass'Test<_T>'で使用しています。   with   {     _T=int   } 前方宣言class Test<_T>;の場合 構文エラー:';'が'<'の前にありません。 構文エラー:'<' 'hoge'が未定義のclass 'Test<_T>'で使用しています。 */ 開発環境: VisualStudio2005 AcademicEdition WindowsXP Professional メモリ:2048MB CPU:Core2Duo 1.33GHz よろしくお願いします。

  • STL に適合するようにクラスを書くとき皆さんはどうしているのでしょう

    大した質問ではないのですが、例えば適当に vector っぽいクラスを template<typename T> class HeppokoVector { private:  いろいろ省略 public:  void push_back(T const& val); }; のように設計したとしましょう。ヘッポコとは言え vector なので STL の std::copy を使って、HeppokoVector<char> hoge; に既存の vector<char> foo; の内容を std::copy(foo.begin(), foo.end(), std::back_inserter(hoge)); な感じでコピーしたいと思いましたが、コンパイルすると 「reference : は HeppokoVector<T> のメンバーではありません」 などと怒られます。back_insert_iterator の定義を見れば、reference や const_reference の定義が必要なので、 template<typename T> class HeppokoVector { private:  いろいろ省略 public:  typedef T& reference;  typedef T const& const_reference;  void push_back(T const& val); }; な風に修正するわけですが、皆さんは自前でコンテナを作る時などに、あらかじめ「コレコレの typedef は必要だな」とか知った上で作成しとるのでしょうか? きっと私が適当なだけなのでしょうが、back_insert_iterator のドキュメントを見ても、push_back が必要であることしかわかりませんでした。

  • templateの抽象クラスについて

    VC++2003の環境なんですが、 下記の状態でtest2.a()を呼び出すと未解決の外部シンボル(LNK2019)のエラーが発生します。同じファイルでこれらを定義した場合は普通に通りました。class内で定義した場合も通ります。なぜでしょうか? test1.h : template<class T> class test1 { public: void a(); }; test1.cpp : template <class T> void test1<T>::a(){} test2.cpp : class test2 : public test1<int> {public:};