• ベストアンサー

templateを使ったときの未解決の外部シンボルエラー

以下のプログラムを、Visual C++ 2008でビルドすると、 『error LNK2019: 未解決の外部シンボル "class A<double> __cdecl add(class A<double> const &,double const &)" (?add@@YA?AV?$A@N@@ABV1@ABN@Z) が関数 _main で参照されました。』 のエラーになります。 template < typename T > class A { private: T x, y; public: A( const T& xx, const T& yy ):x(xx),y(yy){} T getx() const {return x;} T gety() const {return y;} friend A<T> add( const A<T>&, const T& ); }; template < typename T > A<T> add( const A<T>& a, const T& z ){ return A(a.x+z, a.y+z); } /* 直前のテンプレートでこの関数を作ったつもりです A<double> add( const A<double>& a, const double& z){ return A<double>(a.x+z, a.y+z); } /**/ #include <iostream> int main() { A<double> a(1.0, 2.0); double z=3.0; std::cout << add(a,z).getx() << "\n"; } どう書けばよいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

friend A<T> add( const A<T>&, const T& ); ↓ template<typename T> friend A<T> add( const A<T>&, const T& ); ではいかがです?

akayoroshi
質問者

お礼

できました。ありがとうございました。

その他の回答 (1)

  • BLK314
  • ベストアンサー率55% (84/152)
回答No.2

以下のように修正しました template <typename T> class A { private: T x, y; public: A(const T& xx, const T& yy):x(xx),y(yy){}; T getx() const {return x;} T gety() const {return y;} template <typename T>friend A<T> add( const A<T>&, const T& ); }; template <typename T> A<T> add(const A<T>& a, const T& z) { return A<T>(a.x + z, a.y + z); } /* 直前のテンプレートでこの関数を作ったつもりです A<double> add( const A<double>& a, const double& z){ return A<double>(a.x+z, a.y+z); } /**/ #include <iostream> int main() { A<double> a(1.0, 2.0); double z=3.0; std::cout << add(a,z).getx() << "\n"; } これで少なくともビルドは通るはずです 修正点は 1)先ほど指摘されたfriend前にtemplate <typename T>を追加 2)add()内 return A ...でなく         return A<T>...とする 位です ソースで確認してください

akayoroshi
質問者

お礼

ビルドエラーが無くなり、正しく動きました。ありがとうございました。

関連するQ&A

  • 外部ファイルでのtemplate関数の実装方法

    外部ファイルでのtemplate関数の実装方法 sub.cppにtemplate関数を実装し、 main.cppで、sub.cppのtemplate関数を呼び出す、 みたいなことをやりたいのですが、 コンパイルは通りますが、リンクエラー?になってしまいます。 以下が上記のサンプルプログラムです。 //main.cpp #include <vector> #include <iostream> using namespace std; template <typename t_ret, typename t_array> t_ret sub_t(const t_array&); int main (int argc, char *argv[]) { vector<double> v; v.push_back(1.1); v.push_back(2.2); cout << sub_t<double, vector<double> >(v) << endl; return 0; } // sub.cpp #include <vector> using namespace std; template <typename t_ret, typename t_array> t_ret sub_t(const t_array& array) { return array[0]+array[1]; } //コンパイルログ main.o: In function `main': main.cpp:(.text+0x134): undefined reference to `double sub_t<double, std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> > const&)' collect2: ld returned 1 exit status make: *** [main] Error 1 どなたか、対処方法を教えてください。 宜しくお願いします。

  • C++ template operator T()

    ソースを見ていて分からないところがあったので教えて下さい。 なんと説明すればいいのか分からないので下に要約したソースを書きます。 template <typename T> class Hoge { T a_; public: Hoge(T a = 0) : a_(a) {} operator T() const { // ココが分からない return a_; } }; 最初は、関数オブジェクトかと思ったのですがそうではないですよね? operator()(引数) ですよね? 次は、Tのコンストラクタかと思ったのですが、class Hoge の中に書くのも変な気がしました。

  • 「テンプレート」について

    C++でテンプレートについて調べています。 しかし、参考書や参考サイトを見ても下記の例のような、簡易な処理しか載っていないので、 実際にはどのような使われ方をしているのかわかりません。 例1)引数の大小を比較して、小さい方を返す。 template <class T> inline const T& btMin(const T& a, const T& b) { return b < a ? b : a; } 例2)引数の値を入れ替える処理 template <class T> inline void swap(T& a, T& b) { T temp = a; a = b; b = temp; } そこで、参考書や参考サイトなどでは載っていないような、 思いもよらない使われ方をしているものはご存じありませんか? できれば、使われているオープンソースの場所を教えて頂けると嬉しいです。 皆さんどうかよろしくお願い致します。

  • テンプレートが複雑すぎる?

    以下のような文字列比較関数を作ろうと思っています。 ○配列変数であるときは配列版を、そうでないときはポインタ版を呼び出す  配列のサイズがわかるときは、仮に\0で終端していなくてもそれ以上検索しない ○charかwchar_tかを意識せずに使える ○charとwchar_tという記述ではなく、templateでできるだけジェネリック?的に記述したい //charを入れるとwchar_t、wchar_tを入れるとcharを返すメタ関数 template<typename T> struct invert{}; template<> struct invert<char>{ typedef wchar_t t; }; template<> struct invert<wchar_t>{ typedef char t; }; //同じ型同士の比較は省略 //A: 両方ポインタ template<typename T> bool compare(const T *const &v1, const typename invert<T>::t *const &v2); //B1: 左がポインタ、右が配列 template<typename T, size_t L> bool compare(const T *const &v1, const typename invert<T>::t (&v2)[L]); //B2: Tとtypename invert<T>::tを逆に template<typename T, size_t L> bool compare(const typename invert<T>::t *const &v1, const T (&v2)[L]); //C: 左が配列、右がポインタ //省略 //D: 両方配列 template<typename T, size_t L1, size_t L2> bool compare(const T (&v1)[L1], const typename invert<T>::t (&v2)[L2]); char aa[] = "abc"; char *pa = aa; wchar_t aw[] = L"abc"; wchar_t *pw = aw; bool c1 = compare(pa, pw); //A bool c2 = compare(pa, aw); //B1はC2784, B2なら可 bool c3 = compare(aa, pw); //C bool c4 = compare(aa, aw); //DはC2784 invert<T>::t (&v2)[L]という記述が複雑?なのかB1は呼べず、B2と記述すると通りました。 しかしDはどちらも配列であるため、B2のように回避できません。 オーバーロードを全て記述せずに、できるだけ簡単にすます方法はありませんか? 環境はVC++2010です。

  • テンプレートクラス中のフレンドクラス

    下記をg++(fedora core1)でコンパイルしたところ、 #include <iostream> using namespace std; template< typename T > class A {   T a; public:   A(T aa ) : a(aa) { }   friend ostream& operator<<( ostream &os, const A &a ); //9行目 }; template< typename T > ostream& operator<<( ostream &os, const A<T> &a ) { return os << a.a; } int main( ) {   A<int>  a(5);   cout << a << '\n';   return 0; } 9行目にこのような警告・エラーが出てコンパイルできませんでした。(下記のオプションも試してみましたがダメでした) friend declaration 'std::ostream& operator<<(std::ostream&, const A<T>&)' declares a non-template function (if this is not what you intended, make sure the function template has already been declared and add<> after the function name here) -Wno-non-template-friend disables this warning. :undefined reference to 'operator<<(std::basic_ostream <char, std::char_traits<char> >&, A<int> const&)' なぜ、コンパイルできないのかが分かりません。ちなみに、bcc32(borland c++ compiler5.5.1)では同様のエラーが出てコンパイルできず、cl(VC++6.0)ではコンパイル・実行可能でした。 ご存知の方いらっしゃったらご教授お願いします。(bccとclはWinXPです)

  • ラグランジュの補間法のCプログラム

    昨日学校でラグランジュの補間法の問題をC言語のプログラムで解けという課題が出されました しかし、友達と相談してもよくわかりませんでした 課題は以下の問題です sin関数6点、(0.92+0.01x)、x=0,1,2,3,4,5を求めて、ラグランジュの方法でsin(0.923)を計算せよ ちなみに答えは、0.79742です 先生からサンプルのプログラムをもらいました 以下のサンプルプログラムを参考にして解いてくださいと言われたのですが、どうしても解けません すいませんが分かる方、よろしくお願いします #include <stdio.h> #include <math.h> #define N 6 //データ数 double x[N]={ 0.0,1.0,2.0,3.0,3.1,5.0}; //X座標 double y[N]={0.0,1.1,2.5,4.0,4.1,5.0}; //Y座標 double lagrange( double); int main() { double xx,yy; //補間計算 printf("XX\t\tYY\n"); for( xx=0.0; xx<=5.0; xx+=.2 ) { yy = lagrange( xx); printf("%8.2lf\t%8.2lf\n", xx, yy ); } return 0; } //補間サブルーチン double lagrange( double xx ) { double z[N]; double yy=0.0; int i,j; for( i=0; i<N; i++ ) { z[i] = 1.0; //係数計算 for( j=0; j<N; j++ ) if( i!=j ) z[i]*=(xx-x[j])/(x[i]-x[j]); //補間値計算 yy+=z[i]*y[i]; } return yy; } 上記はあくまでサンプルプログラムなので、中に入っている数値は適当です よろしくお願いします

  • テンプレートクラス内のテンプレートクラス(インナークラス)のメソッドを実装ファイルで定義したい

    現在、ヘッダファイル内で下記のようなクラスを宣言・定義しています。 // test.h template < typename T1 > struct A {   template < typename T2 > struct B   {     B( A const& arg ) { ... }   }; }; テンプレートクラスが入れ子になっていて、Bのコンストラクタが引数としてAを取っています。 しかし現状ではコンパイルがとんでもなく遅くなってしまうので、 Bのコンストラクタは宣言のみとし、別途実装ファイル(test.cpp)に定義を書きたいと思っています。 ところがメソッドのシグネチャをどう書けばよいのか分からなくなってしまいました。 苦し紛れに // test.cpp template < typename T1, typename T2 > A<T1>::B<T2>::B( A<T1> const& arg ) { ... } などと書いてみましたが、違うようです。 解決方法はありますでしょうか? 環境はVC7.1かVC8でコンパイルできればよいです。 よろしくお願いいたします。

  • 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; } というふうにしたいんです。 テンプレート関数に引数として構造体にしてそれぞれの要素を参照する場合はどうすれば よろしいのか教えてください。 よろしくお願いします。

  • 偏微分の問題?

    x, y, z の時間微分を: dx/dt = f(x,y,z) dy/dt = g(x,y,z) dz/dt = h(x,y,z) とします。この時、 x = f(xx, y, z) ...(1a) yy = f(xx, y, z) ...(1b) zz = f(xx, yy, z) ...(1c) ∂x /∂xx = (∂yy/∂y)(∂zz/∂z) ...(2) (1)かつ(2)を仮定すると  df/dx + dg/dy + dh/dz = 0 を簡単に示すことができるのだそうです。 ・・・なぜでしょうか?

  • コンパイルエラー。間違ってるのは誰?(どこ?)

    Effective C++の「型変換をさせたいなら、メンバでない関数をクラステンプレートの中で定義しよう」という項目に乗っていたコードを実験してみたのですが、コンパイルでエラーが出るようです。 ----- template<typename T> class Rational { T numerator_value; T denominator_value; public: Rational(const T& num=0, const T& den=1) :numerator_value(num), denominator_value(den){} const T numerator(){return numerator_value;} const T denominator(){return denominator_value;} void show() const { std::cout<<"numerator="<<numerator_value<<": denominator="<<denominator_value<<std::endl; } friend const Rational operator*(const Rational& lhs, const Rational& rhs) //←引数がおかしい? { return Rational(lhs.numerator()*rhs.numerator(), lhs.denominator()*rhs.denominator()); } }; int main() { Rational<int> obj1(1,10); Rational<int> obj2; obj2=obj1*10; obj2.show(); return 0; } ----- こういうコードを書いたのですが、friend関数の部分で「'const Rational<T>' から 'Rational<T> &' へ 'this' ポインタを変換できません」等と怒られます。 引数に取る二つの値のどちらもおかしいようで、コンパイルのエラーを出さないようにするためには、constと&を外さないといけないようです。 引数はEffectiveC++の掲載コードをそのまま使っています。 これは、私のコードがおかしいのか、本のコードがおかしいのかどちらでしょうか?