簡體   English   中英

具有模板參數和返回類型的函數指針

[英]Function pointers with template arguments and return type

看下面的代碼:

struct TestStructure
{
    char mName[256];
    int mSize;

    // Store function pointer with templated argument.
    // Store function pointer with templated return type.
};

class TestClass
{
public:
    void setTestInt(const int& value) { mTestInt = value; }
    const int& getTestInt() const { return mTestInt; }
    void setTestFloat(const float& value) { mTestFloat = value; }
    const float& getTestFloat() const { return mTestFloat; }

    static TestStructure* getTestStructure()
    {
        static TestStructure testStructure[] =
        {
            {"mTestInt", sizeof(int), /* setTestInt pointer, getTestInt pointer */},
            {"mTestFloat", sizeof(float), /* setTestFloat pointer, getTestFloat pointer */}
        };

        return testStructure;
    }

private:
    int mTestInt;
    float mTestFloat;
};

我想要實現的是在TestStructure內部存儲指向該類的各種getter和setter的函數指針(並且該指針必須適用於任何類型)。

有辦法做到嗎?

好像快到2015年了,您現在可能只是在學習C ++:使用兼容C ++ 14的編譯器,此代碼將起作用。

只需使用一個元組來存儲函數指針

template<typename ... Types>
class test_class{
    public:
        template<typename T>
        void set(const T &t){std::get<T>(m_values) = t;}

        template<typename T>
        T &get(){return std::get<T>(m_values);}

        using getters_setters_type = std::pair<std::tuple<Types &(test_class::*)()...>, std::tuple<void (test_class::*)(const Types&)...>>;

        getters_setters_type &getters_and_setters(){
            getters_setters_type ret{
                std::make_tuple(&test_class::get<Types>...),
                std::make_tuple(&test_class::set<Types>...)
            };
            return ret;
        }

    private:
        std::tuple<Types...> m_values;
};

然后舉個例子

int main(){
    test_class<int, float> test_if;
    auto &&getters_and_setters = test_if.getters_and_setters();

    std::function<void(const int&)> set_int(std::bind(std::get<0>(std::get<0>(getters_and_setters)), &test_if, std::placeholders::_1));
    std::function<int&()> get_int(std::bind(std::get<0>(std::get<1>(getters_and_setters)), &test_if));

    // set int to 5
    set_int(5);

    // check it worked
    if(get_int() != 5)
        std::cerr << "dub tee eff, man!" << std::endl;
}

現在,我承認; 看這真是令人作嘔...但是它確實滿足您的要求:D將tuple s放入struct而不是一pair中將是微不足道的。

編輯

我不能只是把答案留在這種病態。 一個人可以很容易地編寫一些輔助函數來提高可讀性:

template<typename T, typename ... Types>
std::function<T&()> get_getter(test_class<Types...> &t){
    return std::bind(
        std::get<T&(test_class<Types...>::*)()>(std::get<0>(t.getters_and_setters())), &t
    );
}

template<typename T, typename ... Types>
std::function<void(const T&)> get_setter(test_class<Types...> &t){
    return std::bind(
        std::get<void(test_class<Types...>::*)(const T&)>(std::get<1>(t.getters_and_setters())), &t, std::placeholders::_1
    );
}

然后在您的主要功能中,您可以編寫

int main(){
    test_class<int, float> test_if;

    auto get_int = get_getter<int>(test_if);
    auto set_int = get_setter<int>(test_if);

    set_int(5);
    if(get_int() != 5)
        std::cerr << "dub tee eff, man!" << std::endl;
}

看起來一點也不差!

暫無
暫無

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

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