CPP奇技淫巧
3 parameter pack
参考:
https://en.cppreference.com/w/cpp/language/parameter_pack
https://kheresy.wordpress.com/2017/05/05/parameter-pack-in-c11/
今天在写一个redis执行命令的函数,然后需要用到不定函数,所以写了一个不定函数的redis调用的函数.代码非常简单就是一个不定函数的调用和执行
template<class ... Types> redisReply* perfom_redis_action(Types ... args) {
redisReply *reply = redisCommand(context_, args...);
int try_times = 0;
int ret_value = SET_TO_REDIS_INTERNAL_ERROR;
/* Connection error will abort directly, connect but reply error will retry */
while (reply == NULL && try_times <= MAX_CONNECT_TIMES) {
LOG(error) << "Error: "<< context_->err;
int connect_status = reconnect();
if (connect_status != CACHE_SERVER_CONNECTED) {
if (try_times == MAX_CONNECT_TIMES) {
return reply;
}
continue;
}
reply = redisCommand(context_, args...);
++try_times;
}
return reply;
}
今天又写了一次parameter pack的奇怪写法,不过理论上使用std::function更合适。
上下文:简单来说就是我有个函数想要每次调用,这个调用的函数应该是可以变化的,可以随意指定
方法1 泛型编程 parameter pack
#include <iostream>
#include <functional>
#include <optional>
// Assuming you have a DataFrame class defined
class DataFrame {
public:
int ref = 0;
// ... Define the DataFrame class implementation
};
void myCallbackFunction(const DataFrame& data, int x, double y) {
std::cout << "Callback function called with DataFrame and arguments: "
<< x << ", " << y << ", "<< data.ref<<std::endl;
}
class Test {
public:
template <class... Types>
using CallbackFunction = std::function<void(const DataFrame&, Types...)>;
template <class... Types>
void setCallback(CallbackFunction<Types...>&& callback) {
void* voidPtr = reinterpret_cast<void*>(&callback);
cb_ = voidPtr;
}
template <class... Types>
void executeCallback(const DataFrame& data, Types... args) const {
if (cb_) {
CallbackFunction<Types...>* function_pointer = static_cast<CallbackFunction<Types...>*>(*cb_);
(*function_pointer)(data, args...);
} else {
std::cout << "Callback not set!" << std::endl;
}
}
std::optional<void*> cb_;
template <class... Types>
void executeFunction(CallbackFunction<Types...>& callback, const DataFrame& data, Types... args) const {
callback(data, args...);
}
};
Test::CallbackFunction<int, double> globalCallbackFunc = myCallbackFunction;
// Outside function that takes Test as an argument
void outsideFunction(Test& testObject) {
testObject.setCallback<int,double>(std::move(globalCallbackFunc));
// Execute the callback using a sample DataFrame
DataFrame data;
data.ref=100;
int arg1 = 4;
double arg2 = 3.1415926;
testObject.executeCallback(data, arg1, arg2);
}
int main() {
Test testObject;
outsideFunction(testObject);
return 0;
}
方法2 使用std::function,更通用的函数对象并不是函数指针,只能感慨真是个菜狗
#include <iostream>
#include <functional>
#include <optional>
// Assuming you have a DataFrame class defined
class DataFrame {
public:
int ref = 0;
// ... Define the DataFrame class implementation
};
void myCallbackFunction(const DataFrame& data, int x, double y) {
std::cout << "Callback function called with DataFrame and arguments: "
<< x << ", " << y << ", "<< data.ref<<std::endl;
}
class Test {
public:
using CallbackFunction = std::function<void(const DataFrame&)>;
void setCallback(CallbackFunction&& callback) {
cb_ = callback;
}
void executeCallback(const DataFrame& data) const {
if (cb_) {
(*cb_)(data);
} else {
std::cout << "Callback not set!" << std::endl;
}
}
std::optional<CallbackFunction> cb_;
};
// Outside function that takes Test as an argument
void outsideFunction(Test& testObject) {
int arg1 = 4;
double arg2 = 3.1415926;
auto callback_function = std::bind(myCallbackFunction,std::placeholders::_1, arg1, arg2);
testObject.setCallback(std::move(callback_function));
// Execute the callback using a sample DataFrame
DataFrame data;
data.ref=100;
testObject.executeCallback(data);
}
int main() {
Test testObject;
outsideFunction(testObject);
return 0;
}
结尾
唉,尴尬