拦截函数调用以在 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);
}
我做了一个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);
}