web-dev-qa-db-ja.com

関数を変数に格納するにはどうすればよいですか?

ファンクターと呼ばれていると思いますか? (久しぶりです)

基本的には、関数へのポインタを変数に格納したいので、コマンドラインから使用する関数を指定できます。

すべての関数が戻り、同じ値を取ります。

_unsigned int func_1 (unsigned int var1)
unsigned int func_2 (unsigned int var1)

function_pointer = either of the above?
_

だから私は行くことによってそれを呼び出すことができます:function_pointer(my_variable)?

編集:@larsmansの提案に従って、私はこれを手に入れました:Config.h:

_class Config
{
public:
    unsigned static int (*current_hash_function)(unsigned int);
};
_

Config.cpp:

_#include "Config.h"
#include "hashes.h"
unsigned static int (*current_hash_function)(unsigned int) = kennys_hash_16;
_

hashes.h:

_unsigned int kennys_hash(unsigned int out);
unsigned int kennys_hash_16(unsigned int out);
_

hashes.cpp:

_just implements the functions in the header
_

main.cpp:

_#include "Config.h"
#include "hashes.h"
// in test_network:
    unsigned int hashed = Config::current_hash_function(output_binary);

//in main():
        else if (strcmp(argv[i], "-kennys_hash_16") == 0)
        {
            Config::current_hash_function = kennys_hash_16;
        }
        else if (strcmp(argv[i], "-kennys_hash_8") == 0)
        {
            Config::current_hash_function = kennys_hash;
        }
_

私が得るエラー:

_g++ -o hPif src/main.o src/fann_utils.o src/hashes.o src/Config.o -lfann -L/usr/local/lib 
Undefined symbols:
  "Config::current_hash_function", referenced from:
      test_network()     in main.o // the place in the code I've selected to show
      auto_test_network_with_random_data(unsigned int, unsigned int, unsigned int)in main.o
      generate_data(unsigned int, unsigned int, unsigned int)in main.o
      _main in main.o // the place in the code I've selected to show
      _main in main.o // the place in the code I've selected to show
      generate_train_file()     in fann_utils.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [hPif] Error 1
_
16
NullVoxPopuli

あなたができる最も簡単なことは

_unsigned int (*pFunc)(unsigned int) = func_1;
_

これはベア関数ポインタであり、フリー関数以外を指すために使用することはできません。

コンパイラがC++ 0x autoキーワードをサポートしている場合は、苦痛を軽減できます。

_auto pFunc = func_1;
_

いずれにせよ、あなたはで関数を呼び出すことができます

_unsigned int result = pFunc(100);
_

一般性を提供する他の多くのオプションがあります。たとえば、次のとおりです。

  • _boost::function_は任意のC++コンパイラで使用できます
  • C++ 0xの機能を実装するコンパイラを使用すると、_std::function_を使用できます。

これらは、適切な署名で呼び出すことができる任意のエンティティを指すために使用できます(実際には、ファンクターと呼ばれるoperator()を実装するオブジェクトです)。

更新(更新された質問に対処するため)

差し迫った問題は、_Config::current_hash_function_(問題なく宣言)を使用しようとしたが、定義に失敗したことです。

これは、_class Config_内の何にも関係のない、関数へのグローバル静的ポインターを定義します。

_unsigned static int (*current_hash_function)(unsigned int) = kennys_hash_16;
_

これは代わりに必要なものです:

_unsigned int (*Config::current_hash_function)(unsigned int) = kennys_hash_16;
_
18
Jon

C++ 0xまたはboostのいずれかから関数を使用することもできます。それは

boost::function<int(int)>

次に、bindを使用して関数をこのタイプにバインドします。

見てください ここここ

ここに例があります。それがお役に立てば幸いです。

int MyFunc1(int i)
{
    std::cout << "MyFunc1: " << i << std::endl;
    return i;
}

int MyFunc2(int i)
{
    std::cout << "MyFunc2: " << i << std::endl;
    return i;
}

int main(int /*argc*/, char** /*argv*/)
{
    typedef boost::function<int(int)> Function_t;

    Function_t myFunc1 = boost::bind(&MyFunc1, _1);
    Function_t myFunc2 = boost::bind(&MyFunc2, _1);

    myFunc1(5);
    myFunc2(6);
}
5
mkaes

いいえ、これらは関数ポインタと呼ばれます。

unsigned int (*fp)(unsigned int) = func_1;
5
Fred Foo

C++ 11からは、std::functionを使用して関数を格納できます。関数を保存するには、それをfollsonigとして使用します。

std :: function <戻り値の型パラメータの型)>

ここでの例として、それは次のとおりです。

#include <functional>
#include <iostream>

int fact (int a) {
    return a > 1 ? fact (a - 1) * n : 1;
}

int pow (int b, int p) {
    return p > 1 ? pow (b, p - 1) * b : b;
}

int main (void) {
    std::function<int(int)> factorial = fact;
    std::function<int(int, int)> power = pow;

    // usage
    factorial (5);
    power (2, 5);
}
4
0x476f72616e
typedef unsigned int (*PGNSI)(unsigned int);

PGNSI variable1 = func_1;
PGNSI variable2 = func_2;
3
Naszta
unsigned int (* myFuncPointer)(unsigned int) = &func_1;

ただし、関数ポインタの構文はひどいので、それらをtypedefするのが一般的です。

typedef unsigned int (* myFuncPointerType)(unsigned int);
myFuncPointerType fp = &func_1;
1

Boost がインストールされている場合は、 Boost Function もチェックアウトできます。

0
yasouser