CPP奇技淫巧

Posted by 大狗 on September 16, 2021

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;
}

结尾

唉,尴尬

狗头的赞赏码.jpg