[英]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.