質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

5022閲覧

クラスのメンバ関数の数値積分

pteryx

総合スコア16

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2016/10/14 09:35

###発生している問題
別のヘッダファイルに書いた数値積分の関数で、クラス内のメンバ関数の数値積分をしたいのですが、以下のエラーメッセージが出てしまいました。
静的メンバでないのが原因のようですが、そのようなメンバ関数を数値積分するにはどうしたらよいのでしょうか?

###エラーメッセージ
rei.cpp: In member function 'double MyClass::factor(double)':
rei.cpp:18:66: error: invalid use of non-static member function
double MyClass::factor(double t) { return exp(trapzd(func,0.,t,30)); }

###該当のソースコード
#####rei.cpp

C++

1#include <iostream> 2#include <cmath> 3#include <cstdlib> 4#include "integral.hpp" 5 6class MyClass{ 7private: 8 double w; 9 double get_w(double t){return w;} 10 double func(double t){ return (1.+ get_w(t))/(1.+ t); } 11public: 12 MyClass(){} 13 MyClass(double a) 14 : w(a) {} 15 double factor(double); 16}; 17 18double MyClass::factor(double t) { return exp(trapzd(func,0.,t,30)); } 19 20 21int main(){ 22 double t = 0.5; 23 MyClass c(-1.); 24 std::cout << c.factor(t) << std::endl; 25 26 return 0; 27} 28 29

#####integral.hpp

C++

1#include <iostream> 2#include <cmath> 3 4double trapzd(double (*func)(double), double a, double b, int n) 5{ 6 double x,tnm,sum,del; 7 static double s; 8 int it,j; 9 if (n == 1) { 10 return (s=0.5*(b-a)*(func(a)+func(b))); 11 } else { 12 for (it=1,j=1;j<n-1;j++) it <<= 1; 13 tnm=it; 14 del=(b-a)/tnm; 15 x=a+0.5*del; 16 for (sum=0.0,j=1;j<=it;j++,x+=del) sum += func(x); s=0.5*(s+(b-a)*sum/tnm); 17 return s; 18 } 19}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

trapzd()関数はパラメータで渡されたfunc()関数を呼び出してますが、func()はMyClassのwをアクセスしています。
つまり、func()はMyClassのメンバ関数ですから、trapzd()関数がfunc()を呼び出す時は、c.func();のようにMyClassのインスタンスを持っている必要が有ります。
しかし、MyClassはcppの中で定義しているため、integral.hppがインクルードするとおかしな事になります。(main()関数の2重定義等)
MyClassをヘッダへ入れて相互参照すれば形式的には解決できますが、trapzd()関数が受け取れるものはMyClassのメンバ関数だけとなります。
ですので、実は結構難易度の高いことに挑戦されています。

trapzd()を関数テンプレートとし、funcを関数オブジェクトとして受け取るようにすればpteryxさんが望まれているものにできると思います。

やっつけなので何か間違っているかも知れませんが、下記のイメージです。

#####rei.cpp

C++

1#include <iostream> 2#include <cmath> 3#include <cstdlib> 4#include "integral.hpp" 5 6class MyClass{ 7private: 8 double w; 9 double get_w(double t){return w;} 10 double func(double t){ return (1.+ get_w(t))/(1.+ t); } 11public: 12 MyClass(){} 13 MyClass(double a) 14 : w(a) {} 15 double factor(double); 16}; 17 18double MyClass::factor(double t) { return exp(trapzd([&](double t){return func(t);},0.,t,30)); } 19 20 21int main(){ 22 double t = 0.5; 23 MyClass c(-1.); 24 std::cout << c.factor(t) << std::endl; 25 26 return 0; 27}
integral.hpp

C++

1#include <iostream> 2#include <cmath> 3 4template<class tFunc> 5double trapzd(tFunc func, double a, double b, int n) 6{ 7 double x,tnm,sum,del; 8 static double s; 9 int it,j; 10 if (n == 1) { 11 return (s=0.5*(b-a)*(func(a)+func(b))); 12 } else { 13 for (it=1,j=1;j<n-1;j++) it <<= 1; 14 tnm=it; 15 del=(b-a)/tnm; 16 x=a+0.5*del; 17 for (sum=0.0,j=1;j<=it;j++,x+=del) sum += func(x); s=0.5*(s+(b-a)*sum/tnm); 18 return s; 19 } 20}

ラムダ式を使っているので、C++11規格に対応したコンパイラが必要になります。

投稿2016/10/14 10:13

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pteryx

2016/10/14 12:13

ありがとうございます! すごいです。うまくいったようです。 ラムダ式というものがあるのですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問