可以是 char*、long 或 int 的函数参数。可能吗?
Function parameter that could be either char*, long or int. Is it possible?
我正在编写一些逻辑来做一些日志记录,有一堆 C++ 与 C 混合,因为这个库的大部分都是 p/Invoked。我已经设法编写了一个记录消息和可选参数的函数:
void writeToLog(char* message, char* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg != 0)
fullMessage.append(arg);
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}
然而它只需要 char* 作为参数,但我想将它们与 int 和 long 一起使用......我已经尝试过:
void writeToLog(char* message, void* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg != 0)
fullMessage.append((char*)&arg);
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}
但它 prints/writes 乱码,无论数据类型如何。请指出您认为合适的任何其他错误,关于 C/C++.
我有点菜鸟
您可以通过两种方式解决此问题。第一种方法是重载函数。这意味着您将一遍又一遍地编写相同的函数,只是使用不同的类型作为参数。
例子
#include <iostream>
using namespace std;
class printData {
public:
void print(int i) {
cout << "Printing int: " << i << endl;
}
void print(double f) {
cout << "Printing float: " << f << endl;
}
void print(char* c) {
cout << "Printing character: " << c << endl;
}
};
int main(void) {
printData pd;
// Call print to print integer
pd.print(5);
// Call print to print float
pd.print(500.263);
// Call print to print character
pd.print("Hello C++");
return 0;
}
此代码打印:
Printing int: 5
Printing float: 500.263
Printing character: Hello C++
第二个选项是使用模板。基本上,你会做
template<class T>
void writeToLog(char* message, T arg){
//continue to write code here without assuming anything about the type of arg
}
用于重载函数的link:https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm
我的建议:
- 将函数更改为函数模板。
- 使用标准库函数
std::to_string
将数字转换为 std::string
。添加一些包装代码,以便您可以使用相同的函数调用来处理 char*
和 char const*
.
- 使用包装函数的 return 值附加到正在写入的消息。
- 删除对
std::string::c_str()
的调用。 std::string
可以写入文件,std::cout
.
- 不需要调用
file.close();
。函数returns. 时会关闭
namespace my_app
{
template <typename T>
std::string toString(T in)
{
return std::to_string(in);
}
std::string toString(char const* in)
{
return std::string(in);
}
std::string toString(std::string const& in)
{
return in;
}
}
template <typename T>
void writeToLog(char* message, T arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
fullMessage.append(my_app::toString(arg));
fullMessage.append("\n");
file << fullMessage;
std::cout << fullMessage;
}
}
// Overload to deal with the optional parameter
void writeToLog(char* message) {
writeToLog(message, "");
}
您可以使用模板。
这是一个向您展示基本思想的简单示例。 (虽然没有测试)
template <typename T, typename U>
void func(T param1, U param2)
{
std::cout << param1 << param2;
}
在主要例子中:
func("A", 5);
func (2, 2.5);
您需要阅读一些内容才能完成您的需要。
任何托管的 object
都可以编组为 VARIANT
。当然,如果您这样做,编译器将不会进行任何类型检查。
// C# P/Invoke
static extern void writeToLog(string message, ref object arg);
// C++
void writeToLog(const char* message, const VARIANT* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg) {
switch (V_VT(arg)) {
case VT_I4:
message.append(V_I4(arg));
break;
case VT_I8:
message.append(V_I8(arg));
break;
case VT_BSTR:
message.append(V_BSTR(arg));
break;
}
}
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}
我正在编写一些逻辑来做一些日志记录,有一堆 C++ 与 C 混合,因为这个库的大部分都是 p/Invoked。我已经设法编写了一个记录消息和可选参数的函数:
void writeToLog(char* message, char* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg != 0)
fullMessage.append(arg);
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}
然而它只需要 char* 作为参数,但我想将它们与 int 和 long 一起使用......我已经尝试过:
void writeToLog(char* message, void* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg != 0)
fullMessage.append((char*)&arg);
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}
但它 prints/writes 乱码,无论数据类型如何。请指出您认为合适的任何其他错误,关于 C/C++.
我有点菜鸟您可以通过两种方式解决此问题。第一种方法是重载函数。这意味着您将一遍又一遍地编写相同的函数,只是使用不同的类型作为参数。 例子
#include <iostream>
using namespace std;
class printData {
public:
void print(int i) {
cout << "Printing int: " << i << endl;
}
void print(double f) {
cout << "Printing float: " << f << endl;
}
void print(char* c) {
cout << "Printing character: " << c << endl;
}
};
int main(void) {
printData pd;
// Call print to print integer
pd.print(5);
// Call print to print float
pd.print(500.263);
// Call print to print character
pd.print("Hello C++");
return 0;
}
此代码打印:
Printing int: 5
Printing float: 500.263
Printing character: Hello C++
第二个选项是使用模板。基本上,你会做
template<class T>
void writeToLog(char* message, T arg){
//continue to write code here without assuming anything about the type of arg
}
用于重载函数的link:https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm
我的建议:
- 将函数更改为函数模板。
- 使用标准库函数
std::to_string
将数字转换为std::string
。添加一些包装代码,以便您可以使用相同的函数调用来处理char*
和char const*
. - 使用包装函数的 return 值附加到正在写入的消息。
- 删除对
std::string::c_str()
的调用。std::string
可以写入文件,std::cout
. - 不需要调用
file.close();
。函数returns. 时会关闭
namespace my_app
{
template <typename T>
std::string toString(T in)
{
return std::to_string(in);
}
std::string toString(char const* in)
{
return std::string(in);
}
std::string toString(std::string const& in)
{
return in;
}
}
template <typename T>
void writeToLog(char* message, T arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
fullMessage.append(my_app::toString(arg));
fullMessage.append("\n");
file << fullMessage;
std::cout << fullMessage;
}
}
// Overload to deal with the optional parameter
void writeToLog(char* message) {
writeToLog(message, "");
}
您可以使用模板。
这是一个向您展示基本思想的简单示例。 (虽然没有测试)
template <typename T, typename U>
void func(T param1, U param2)
{
std::cout << param1 << param2;
}
在主要例子中:
func("A", 5);
func (2, 2.5);
您需要阅读一些内容才能完成您的需要。
任何托管的 object
都可以编组为 VARIANT
。当然,如果您这样做,编译器将不会进行任何类型检查。
// C# P/Invoke
static extern void writeToLog(string message, ref object arg);
// C++
void writeToLog(const char* message, const VARIANT* arg) {
std::ofstream file;
file.open(fullpath, std::ios::in | std::ios::app);
if (file.is_open()) {
std::string fullMessage = getCurrentDateTime();
fullMessage.append(message);
if (arg) {
switch (V_VT(arg)) {
case VT_I4:
message.append(V_I4(arg));
break;
case VT_I8:
message.append(V_I8(arg));
break;
case VT_BSTR:
message.append(V_BSTR(arg));
break;
}
}
fullMessage.append("\n");
const char* pcMessage = fullMessage.c_str();
file << pcMessage;
std::cout << pcMessage;
}
file.close();
}