2016-09-14 11 views
4

私のコードにいくつかの重要なことをするいくつかのvoid関数があります。引数を受け取り、void関数へのポインタを返す関数

void function1(Myclass class1, int myvar) 
{ 
    // do some stuff 
} 

void function2(Myclass class1, int myvar) 
{ 
    // do some other stuff 
} 

// ... maybe some more similar functions 

私が渡す引数に応じて、これらの関数のいずれかへのポインタを返す関数を作成します。私はそれをする方法を知らない。

void* choosefunction(int i, int j) 
{ 
    if (i == j) return (void*)function1; 
    else return (void *)function2; 
} 

私はちょうどこのポインタによってそれらを呼び出すでしょう。

void *(*ptrProcFunc)(int,int); 
ptrProcFunc = &choosefunction; 
(*ptrr)() = ptrProcFunc(i,j); 
ptrr(class1,myvar); 

正しく行うにはどうすればよいですか?ありがとうございました。

答えて

6

typedefはあなたの友人です。その後

typedef void (*func_ptr)(Myclass, int); 

func_ptr choosefunction(int i, int j) 
{ 
    if (i == j) return &function1; 
    else return &function2; 
} 

:ここ

func_ptr ptrr = choosefunction(i,j); 

ptrr(class1,myvar); 
+0

あなたは、このことを指摘してくれてありがとう正しいです。 –

+0

もう一つのオプションは、ポインタ型宣言を使用しないことです。IMOコードは、ポインタ宣言に '*'があると読みやすくなります –

+1

C++ 11以上が利用可能な場合は、別名形式を前提とします: 'func_ptr = void (Myclass、int); '私はそれがもっと明確だと思う。 –

1

は完全な例です。

#include <functional> 
#include <iostream> 

// Typedef for convenience, called "fcn". 
typedef void(*fcn)(int, int); 

// You could also use c++11's std::function, which is easier 
// to read than function pointers. 
typedef std::function<void(int, int)> modern_fcn; 

void func1(int a, int b) { 
    std::cout << "func1" << std::endl;  
} 

void func2(int a, int b) { 
    std::cout << "func2" << std::endl; 
} 

// This returns our typedef'd function pointer. 
fcn pick(int i, int j) { 
    if (i == j) { 
     return &func1; 
    } else { 
     return &func2; 
    } 
} 

int main() 
{ 
    // Should call func1. 
    pick(1,1)(3, 5); 

    // Should call func2. 
    pick(1,2)(3, 5); 
} 
1

あなたは、いくつかのオプションがあります。

  • あなたはあなたのタイプのために別名を導入するために使用して宣言を使用することができます:あなたはauto指定子を使用することができます

    using func_ptr = void (*)(Myclass, int); 
    using choose_ptr = void *(*)(int,int); 
    
    // ... 
    
    func_ptr choosefunction(int i, int j) { 
        if (i == j) return &function1; 
        else return &function2; 
    } 
    
    // ... 
    
    choose_ptr ptrProcFunc = &choosefunction; 
    func_ptr ptrr = ptrProcFunc(i,j); 
    ptrr(class1,myvar); 
    
  • をし、それだけです(C++ 14):

    auto choosefunction(int i, int j) { 
        if (i == j) return &function1; 
        else return &function2; 
    } 
    
    // ... 
    
    auto ptrProcFunc = &choosefunction; 
    auto ptrr = ptrProcFunc(i,j); 
    ptrr(class1,myvar); 
    
  • あなたがauto指定し、末尾のタイプ(C++ 11)を使用することができます。この場合

    auto choosefunction(int i, int j) -> decltype(&function1) { 
        if (i == j) return &function1; 
        else return &function2; 
    } 
    
    // ... 
    
    auto ptrProcFunc = &choosefunction; 
    auto ptrr = ptrProcFunc(i,j); 
    ptrr(class1,myvar); 
    

    を、我々はfunction1function2が同じ型を持っているという事実を利用します。

1

(醜い)構文はusing(またはtypedef)で

void (*choosefunction(int i, int j))(Myclass, int) 
{ 
    if (i == j) return &function1; 
    else return &function2; 
} 

あり、それが読めるようになります。

using F = void(Myclass, int); 
using FPtr = void(*)(Myclass, int); // or using FPtr = F*; 

そして

F* choosefunction(int i, int j); 

または

FPtr choosefunction(int i, int j); 

あなたのインライン定義場合autoシンプルな使用、あなたがC++ 14であり:

FPtr f = choosefunction(i, j); 

f(myclass, myvar); 
1

あなたの混乱(とI:

とにかく
auto choosefunction(int i, int j) { 
    if (i == j) return &function1; 
    else return &function2; 
} 

を、使い方のようなものになるだろうCやC++を学ぶ人々の多くでこれを見てきました))は、それらが "void関数"ではないということです。せいぜいあなたは何も返さない関数であると言うことができます(もしあなたがもう少しリラックスして言語を濫用すれば、それらはvoidを返す関数だと言うことができます)。それらは関数はMyclassint引数を受け取り、何も返さないです。

その他の回答は、その達成方法を示しています。

int a 

using func_ptr = void (*)(Myclass, int); 

混乱(と思う)のソースは、あなたが最初の変数宣言を学ぶことです:私は強く、特に関数型のため、typedefの代わりにusingを使用することをお勧めします

と宣言されたエンティティのタイプは、その名前が付けられています。

は、その後、あなたが機能を学び、あなたが書く:

int sum(int a, int b) 

と(間違った)類推によってあなたが言う:が宣言されているエンティティは、それのタイプは、それはすなわち、残って上に書かれているものでなければならないsumあるint 。だからあなたは「合計はタイプintです」と言っています。これは間違っていてOPのもののような混乱を招きます。

sumのタイプは、「関数として2つの整数を受け取り、整数を返す関数」です。新しい末尾の戻り型の宣言構文で関数を考え、あなたの習慣を当てる助け書いたり、少なくともする

auto sum(int a, int b) -> int 
関連する問題