2010-05-20 77 views
1

我正试图改进现有C++程序中的SQLite错误处理。我有一个自定义类型SQLiteException,并且我想写一个宏来打印SQL的行号,文件名和错误消息。变量参数和函数重载

我已经定义了以下功能:

LogMessage(LPCTSTR message); // Does the real work. Appends a timestamp to the message and logs the message to disk 

LogMessage(LPCSTR message); // Simply converts message from ASCII to UNICODE and calls the original LogMessage(LPCTSTR message) function. 

LogMessage(LPCTSTR message, ...); // A new variable argument version of the function. It uses vsprintf to format into a temporary TCHAR string, and passes that string into the first LogMessage(LPCTSTR message) function. 

这是我遇到的麻烦。编译器抱怨对重载函数的模糊呼叫。第三个功能是实现这样的:

void LogMessage(LPCTSTR message, ...) 
{ 
TCHAR logBuffer[513]; 
va_list args; 
va_start(args, message); 
_vsntprintf(logBuffer, 512, message, args); 
va_end(args); 
LogMessage((LPCTSTR)logBuffer); 
} 

}

我已经加入宏是这样写的:

#define LOG_SQLITE_EXCEPTION(e) LogMessage(_T("%s %s %d"), CString(__FUNCTION__), CString(__FILE__), __LINE__); LogMessage(GetSQLiteErrorMessage(e)); 

我怎样才能使编译器调用的LogMessage的第一个版本函数在执行第三个版本?编译器似乎忽略了'...'参数,并且无法分辨LogMessage的第一个和第三个实现之间的区别。

回答

3

那么,这些是可变参数 - 意味着零参数也是可以接受的。在这种情况下,编译器将无法在第一个和第三个函数之间进行选择,因为它们的第一个参数是相同的。

+0

我会推荐给这些功能(一点点)更具描述性的名称。 – nielsj 2010-05-20 16:07:17

+0

这条线btw:LogMessage((LPCTSTR)logBu​​ffer); – nielsj 2010-05-20 16:08:42

+0

我将更改名称,以使编译器和其他程序员更清楚。 – 2010-05-20 16:51:59

0

尝试使第三个版本更加严格,从而需要额外的参数:

template<typename T> 
LogMessage(LPCTSTR message, T _, ...) 
{ 
    (T)_; 
    // implementation same as above 
}