可以是 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

link 模板:http://www.cplusplus.com/doc/oldtutorial/templates/

我的建议:

  1. 将函数更改为函数模板。
  2. 使用标准库函数 std::to_string 将数字转换为 std::string。添加一些包装代码,以便您可以使用相同的函数调用来处理 char*char const*.
  3. 使用包装函数的 return 值附加到正在写入的消息。
  4. 删除对 std::string::c_str() 的调用。 std::string 可以写入文件,std::cout.
  5. 不需要调用file.close();。函数returns.
  6. 时会关闭

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