への変更:
A( double (*f)() )
{
size = f();
};
と:
A a = A( fun1 );
あなたが通り過ぎていたとき &fun1()
それは関数を呼び出して、その結果のアドレスを取得しようとしていました。あなたが実際に望んでいたのは、に保存されている機能ポインター自体でした fun1
.
質問
変数が異なる関数に依存するオブジェクトをいくつか取得しました。異なる言葉で言うには、オブジェクトの変数が依存する関数には複数のタイプがありますが、これらの関数と同じで複数のオブジェクトがあるはずです。より多くのクリアランスのために、私は例を挙げようとしました(これは機能しません)。
#include <iostream>
class A
{
double size;
A( double (*f)() )
{
size = (*f)();
};
};
double fun1()
{
return 42.0;
}
int main()
{
A a = A( &fun1() );
std::cout << a.size << std::endl;
}
もちろん、これは最小限の例です。変数サイズは、クラスへの引数として渡す必要がある特定の関数に依存します。想像 fun1
と fun2
さまざまな種類の乱数ジェネレーターとして。
C ++のイデオマチックな方法は変数を保持するクラスであり、そこから継承されたクラスはオブジェクトを異なる関数によって変更されると思います(この仮定が間違っている場合は修正してください)。しかし、私の質問は次のとおりです。
ある種の高次コンストラクターを実装する可能性はありますか?もしそうなら、例がいいでしょう。
PS:いくつかの技術用語を間違えた場合、修正できてうれしいです。
解決
への変更:
A( double (*f)() )
{
size = f();
};
と:
A a = A( fun1 );
あなたが通り過ぎていたとき &fun1()
それは関数を呼び出して、その結果のアドレスを取得しようとしていました。あなたが実際に望んでいたのは、に保存されている機能ポインター自体でした fun1
.
他のヒント
この例は意味がありません。なぜなら、後で使用するために関数ポインターを保存しないからです。これを単純に書き換えることができます
class A
{
double size;
A(double sz) {
size = sz;
};
};
double fun1()
{
return 42.0;
}
int main()
{
A a = A(fun1());
std::cout << a.size << std::endl;
}
代わりにテンプレートを書くことをお勧めします。そうすれば、任意の関数ポインターまたは関数オブジェクトを渡すことができます。これにより、コンパイラは多くの場合、インランスのような最適化をより簡単に実行でき、より柔軟になります。また、関数ポインターを取得するときに括弧を使用しないでください。
#include <iostream>
class A {
public:
template<typename F>
explicit A(F&& f) : size(f()) {
};
double size;
};
double fun1() {
return 42.0;
}
int main() {
A a(&fun1);
std::cout << a.size << std::endl;
}
渡すには関数自体のみが必要なようです。あなたはほとんどそれを手に入れました。これが正しい構文です:
typedef double (*functype)();
void foo(functype f) {
cout << f();
}
double bar() {
return 2.39;
)
foo(bar); // don't call bar here, just pass it as address.
次のようにfooを宣言することもできます。
void foo(double (*f)());
関数はC ++のファーストクラスのオブジェクトではないため、いくつかの変数を使用してクロージャーを作成する唯一の方法(たとえば、関数を運びたい場合、または非静的なメンバー関数を呼び出す場合)はファンクター(オーバーロードされたオペレーターを持つオブジェクト()です。 )。そのようなオブジェクトを取得する方法はいくつかあります: