簡體   English   中英

通過boost傳遞函數指針參數

[英]Passing function pointer arguments with boost

通過使用boost :: function和/或boost :: bind可以簡化/改進以下函數指針的傳遞嗎?

void PassPtr(int (*pt2Func)(float, std::string, std::string))
{
   int result = (*pt2Func)(12, "a", "b"); // call using function pointer
   cout << result << endl;
}

// execute example code
void Pass_A_Function_Pointer()
{
   PassPtr(&DoIt);
}

您可以使用boost::function<>來使用不同類型的可調用對象作為函數的輸入。

以下是使用C ++ 11的示例(請參見此示例后的備注)。 這是重寫函數的方式:

#include <functional>
#include <string>
#include <iostream>

void PassFxn(std::function<int(float, std::string, std::string)> func)
//           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
   int result = func(12, "a", "b"); // call using function object
   std::cout << result << std::endl;
}

這些是用於測試它的幾個函數:

int DoIt(float f, std::string s1, std::string s2)
{
    std::cout << f << ", " << s1 << ", " << s2 << std::endl;
    return 0;
}

int DoItWithFourArgs(float f, std::string s1, std::string s2, bool b)
{
    std::cout << f << ", " << s1 << ", " << s2 << ", " << b << std::endl;
    return 0;
}

struct X
{
    int MemberDoIt(float f, std::string s1, std::string s2)
    {
        std::cout << "Member: " << f << ", " << s1 << ", " << s2 << std::endl;
        return 0;
    }

    static int StaticMemberDoIt(float f, std::string s1, std::string s2)
    {
        std::cout << "Static: " << f << ", " << s1 << ", " << s2 << std::endl;
        return 0;
    }
};

這是測試例程:

int main()
{
    PassFxn(DoIt); // Pass a function pointer...

    // But we're not limited to function pointers with std::function<>...

    auto lambda = [] (float, std::string, std::string) -> int
    {
        std::cout << "Hiho!" << std::endl;
        return 42;
    };

    PassFxn(lambda); // Pass a lambda...

    using namespace std::placeholders;
    PassFxn(std::bind(DoItWithFourArgs, _1, _2, _3, true)); // Pass bound fxn

    X x;
    PassFxn(std::bind(&X::MemberDoIt, x, _1, _2, _3)); // Use a member function!

    // Or, if you have a *static* member function...
    PassFxn(&X::StaticMemberDoIt);

    // ...and you can basically pass any callable object!
}

這是一個生動的例子

備注

如果您使用的是C ++ 03,則可以輕松地將std::function<>更改為boost::function<> ,將std::bind<>更改為boost::bind<> (實際上,Boost.Function是受啟發的std::function<> ,后來成為標准C ++庫的一部分)。 在這種情況下,您必須包括boost/function.hppboost/bind.hpp標頭(僅當您想使用boost::bind時才使用后者),而不是包含<functional>標頭。

進一步的示例應該讓您感受到std::function<> / boost::function<>通過封裝任何類型的可調用對象的能力賦予您的力量,另請參閱StackOverflow上的此問答

我假設您想改善PassPtr的功能,而不是您提供的所有示例代碼。 如果您使用的是C ++ 11,並且可以使用lambda表達式,那么我可以將其簡化為:

template <typename Func>
void PassPtr(Func f) {
  std::cout << f(12, "a", "b") << std::endl;
}

這將允許任何可調用對象作為f傳遞。 通過推導的模板類型采用函數的原因是允許內聯任何傳遞的lambda。 當然,這不會對傳遞的函數強制執行任何特定的簽名(或者甚至應將其作為可調用對象)。 例如,如果您傳遞一個int ,您將得到一些令人困惑的編譯器錯誤。

使用[boost|std]::function的替代方法是:

void PassPtr(std::function<int(float, std::string, std::string)> f) {
  std::cout << f(12, "a", "b") << std::endl;
}

就像上面一樣,這將允許傳遞任何類型的可調用對象,但可能不會導致內聯lambda。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM