5

matlab では、次のように記述できます。

S = @(x,y) x^2+y^2-1
G = @(x) S(x,1);

引数が 1 つの関数を期待する関数がある場合は、上記を実行できます。c/c++ でこれを行うにはどうすればよいですか?

引数として、それ自体が 1 つの引数しか持たない関数を期待するライブラリ関数 (CGAL ライブラリから) があります。理想的には、クラス ( SphericalHarmonics) があり、1 つの引数を取るメンバー関数が必要です。ので、私は持っています:

FT SphericalHarmonics::distFunction(Point_3 p)

FT(に似たタイプであることに注意してくださいdouble)もちろん、試してみると

SphericalHarmonics *sh = new SphericalHarmonics(1);
Surface_3 surface(sh->distFunction, Sphere(ORIGIN,2.));

thisも引数として扱われる場合、distFunction関数は 2 つの引数の関数であり、エラーがスローされます。

これはグローバル変数で解決できることに注意してください。

SphericalHarmonics *sh;
FT dist_function(Point_3 p) {
    return sh->distFunction(p);
}

main() {
    sh = new SphericalHarmonics(1);
    Surface_3 surface(dist_function);
}

ただし、これは実際には理想的ではありません。CGAL ライブラリと簡単に統合できるクラス関数を使用できる方がはるかに優れているため、グローバル変数を使用せずにこれを行う方法が必要です。

前もって感謝します!

[更新しました]

@ Andy-Prowl: 私はあなたstd::bindlambda解決策を試しましたが、引数の数に関してまだエラーが発生しているようです.

main、コードを使用する場合:

SphericalHarmonics *sh = new SphericalHarmonics(cInit, numL, symm);
auto fxn = std::bind(&SphericalHarmonics::distFunction, sh, std::placeholders::_1);
Surface_3 surface(fxn, Sphere_3(ORIGIN,2.));

エラーが発生します:

~/lib/basisfunctions/SphericalHarmonics2/mesh_an_implicit_function.cpp:62:48: 
error: no matching function for call to     
‘CGAL::Implicit_surface_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, 
double (*)
(CGAL::Point_3<CGAL::Epick>)>::Implicit_surface_3(std::_Bind<std::_Mem_fn
<double (SphericalHarmonics::*)(CGAL::Point_3<CGAL::Epick>)>
(SphericalHarmonics*, std::_Placeholder<1>)>&, Sphere_3)’

~/CGAL-4.1/include/CGAL/Implicit_surface_3.h:50:5: note:   no known conversion 
for argument 1 from ‘std::_Bind<std::_Mem_fn<double (SphericalHarmonics::*)
(CGAL::Point_3<CGAL::Epick>)>(SphericalHarmonics*, std::_Placeholder<1>)>’ to 
‘CGAL::Implicit_surface_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>, 
double (*)(CGAL::Point_3<CGAL::Epick>)>::Function 
{aka double (*)(CGAL::Point_3<CGAL::Epick>)}’

~/CGAL-4.1/include/CGAL/Implicit_surface_3.h:34:9: note:   
candidate expects 1 argument, 2 provided

[更新しました]

関数ポインターに変換できる関数が必要であることは明らかです (つまりsurface、関数ポインターの引数が必要です)。これにより、std::bindオプションが除外されます。さらに、ラムダが変数をキャプチャする場合、ラムダを関数ポインタに変換できないようです(キャプチャレスとラムダのキャプチャ)。したがって、以下の Andy-Prowl の回答は、一般的にこの質問に対する正しい回答だと思いますが、別の回避策を見つける必要があります。

4

3 に答える 3

5

std::bindまたはboost::bind:を使用します

#include <functional>   

SphericalHarmonics *sh = new SphericalHarmonics(1);
surface(std::bind(&SphericalHarmonics::distFunction, sh, _1));
于 2013-02-28T00:17:59.387 に答える
5

オプション1:

メンバー関数がクラスのインスタンスで暗黙的に機能しない場合(したがって、thisポインターを受け取る必要がない場合)、次のようにすることができますstatic

class SphericalHarmonics
{
    ...
    static double distFunction(Point p);
    ...
};

double SphericalHarmonics::distFunction(Point p)
{
    ...
}

これで、関数には事実上1つの引数があります。

surface(SphericalHarmonics::distFunction);

オプション2:

それ以外の場合は、を使用std::bind()してメンバー関数をカレーしdistFunction、最初の暗黙の引数を修正できます(C ++ 11コンパイラを使用していない場合はboost::bind()Boost.Bindライブラリの同等の引数を使用できます)。

#include <functional>

SphericalHarmonics *sh = new SphericalHarmonics(1);
auto fxn = std::bind(&SphericalHarmonics::distFunction, sh, _1);
surface(fxn);

オプション3:

あるいは、C ++ 11では、ラムダがその仕事をすることができます。

SphericalHarmonics *sh = new SphericalHarmonics(1);
auto fxn = [=] (double d) { return sh->distFunction(d); } 
于 2013-02-28T00:18:19.713 に答える