拦截函数调用以在 if 之前添加参数

Intercept the function call to add a argument before an if

我做了一个console.log函数来模仿javascriptconsole.log函数。我遇到的问题是在所有参数之后换行,因为我无法检测何时是单个参数调用,或者是由于函数过载而调用的最后一个参数。

我认为的解决方案是在头文件中的函数上添加一个新参数。

所以当我在 main.cpp 中写入时:

console.log("hello");
console.log("bye");

我希望你帮我在从头文件获取的任何处理之前添加一个新参数:

console.log("hello", "");
console.log("bye", "");

完整代码在这里。 https://github.com/StringManolo/cppjs/blob/main/console/log.h#L17

这是您要求的最小可重现示例: main.cpp

#include "./log.h"

int main() {

  /* Each console.log call should add a line break */
  console.log("Line1");
  console.log("Line2");
  console.log("Line3");

  /* Like Here */
  console.log("Line1", "");
  console.log("Line2", "");
  console.log("Line3", "");

  /* Then i can do: */
  console.log("Welcome.");
  console.log("7 * 8 = ", 7 * 8);
  console.log("Bye!");

  std::vector<std::string> example = {"a", "b", "c", "d", "e"};
  console.log(example);

  std::any numberOrString = 1337;
  console.log(numberOrString);

  numberOrString = (std::string) "String";
  console.log(numberOrString);

  /* stdout :
  $ ./test
  Line1Line2Line3Line1
  Line2
  Line3
  Welcome.7 * 8 = 56
  Bye!a, b, c, d, e
  1337
  String
  */

  /* Desired output:
  Line1
  Line2
  Line3
  Line1
  Line2
  Line3
  Welcome.
  7 * 8 = 56
  Bye!
  a, b, c, d, e
  1337
  String
  */

  return 0;
}

log.h

#pragma once

#include <iostream>
#include <utility>
#include <any>
#include <vector>
#include <string>

struct {
  std::any aux;

  template<typename T, typename...Args>
  static void log(T&& t, Args&&... args) {

    log(t);
    log(std::forward<Args>(args)...);
    if(sizeof...(args) > 1) {

    } else {
      std::cout << "\n";
    }

  }

  static void log(int arg) {
    std::cout << arg;
  }

  static void log(const char* arg) {
    std::cout << arg;
  }

  static void log(std::vector<std::string> arg) {
    for(int i = 0; i < arg.size(); ++i) {
      if (i + 1 == arg.size()) {
        std::cout << arg[i] << std::endl;
      } else {
        std::cout << arg[i] << ", ";
      }
    }
  }

  template<typename T>
  static void log(T&& t) {
    if (typeid(t).name() == typeid(aux).name()) {
      try {
        std::any_cast<std::string>(t);
        std::cout /* ANY */<< std::any_cast<std::string>(t) << std::endl;
      } catch (const std::bad_any_cast& a) {
        //std::cout << a.what() << '\n';
        try {
          std::any_cast<int>(t);
          std::cout /* ANY */<< std::any_cast<int>(t) << std::endl;
        } catch (const std::bad_any_cast& b) {
          std::cout << a.what() << "\n";
        }
      }

    } else {
      std::cout << "THE TYPE (" << typeid(t).name() << ") NOT OVERLOADED" << std::endl;
    }
  }
} console;

我在 console.log() 调用中需要超过 1 个参数来触发换行。

如何在 if 被评估之前拦截推送参数的调用?

编译命令:

g++ -o test main.cpp -std=c++17

编译完整代码的命令:

g++ -o program main.cpp -lcurl -std=c++17

您可能应该使用不同的名称:

template <typename ...Ts>
static void log(Ts&&... ts)
{
    (do_log(ts), ...);
    std::cout << "\n";
}

// private:
template <typename T>
static void do_log(const T& arg) {
    std::cout << arg;
}

template <typename T>
static void do_log(const std::vector<T>& v)
{
    std::cout << '{';

    const char* sep = "";
    for (const auto& e : v) {
        std::cout << sep;
        do_log(e);
        sep = ", ";
    }
    std::cout << '}';
}

template <typename T>
static bool try_log_any(const std::any& arg) {
    if (auto* p = std::any_cast<T>(&arg)) {
        do_log(*p);
        return true;
    }
    return false;
}

template <typename... Ts>
static bool try_log_any_from(const std::any& arg) {
    if ((try_log_any<Ts>(arg) || ...)) {
        return true;
    }
    std::cout << "unsupported any type" << std::endl;
    return false;
}

static void do_log(const std::any& arg) {
    try_log_any_from<std::string, int, unsigned, char, float, double /*..*/>(arg);
}

Demo