1

I have the following defined:

void LogMessage(PCTSTR text);
void LogMessage(PCTSTR format, ...);

If I just want to call the function with one parameter, I get the following error message:

Source.cpp(10): error C2668: 'Log' : ambiguous call to overloaded function
  could be 'void Log(PCTSTR,...)' or 'void Log(PCTSTR)'
  while trying to match the argument list '(const wchar_t [42])'

Is it possible to do a static_cast to explizite use the first version? Or haw can this be solved, except by renaming the first or second function?

Jochen Kalmbach
  • 3,549
  • 17
  • 18
  • You only need `void LogMessage(PCTSTR format, ...);` – πάντα ῥεῖ Dec 16 '14 at 08:03
  • No... if someone uses `Log(_T("Log%text"))` I get a problem... that´s the reason I want two function.... the first calls internally the second with `Log(_T("%s"), text);`... – Jochen Kalmbach Dec 16 '14 at 08:11
  • 1
    _"No... if someone uses Log(_T("Log%text")) I get a problem.."_ What about checking the `format`, in case of no arguments? If you just blindly forward it, you'll have a problem yes. – πάντα ῥεῖ Dec 16 '14 at 08:13
  • Hmm... there is no way to count the arguments... The problem is that I have an existing large codebase... and sometimes the string is build before it is passed to this function... and sometimes a used-input in insert which contains a "%"... therefore I am searching for a "simple" way to handle this situation, if no arguments are passed... – Jochen Kalmbach Dec 16 '14 at 08:31
  • Can you extend your question with the current implementation of the `LogMessage()` functions please? May be someone knows a trick how to get it from the [`va_list`](http://en.cppreference.com/w/cpp/utility/variadic/va_list) argument. – πάντα ῥεῖ Dec 16 '14 at 08:51
  • You can write a little script/a fewlines of code, that checks for lines with `LogMessage(` and check if there are comma outside of the string argument(s) before the `)` at the end. No, you probably can't use regex. If there are no commas, then check if the string contains `%`, and issue a message with filename and line-number. – Mats Petersson Dec 16 '14 at 08:51
  • People are rushing to hit the close and downvote buttons... this is a decent question! – Nik Bougalis Dec 16 '14 at 08:58

1 Answers1

2

How about the following? I haven't tested on VC++ (which seems to be your platform of choice) but hopefully the version you are using implements enough C++11 for this to work.

#include <iostream>
#include <cstdio>
#include <cstdarg>

void LogMessageWorker(char const* format, ...)
{
    // 1k should be enough for anyone... ;)
    char buf[1024] = { 0 };

    // The version of vsnprint called should always null terminate correctly and doesn't
    // strictly need the -1 but I believe that the implementation that is included with
    // VC++ leaves a lot to be desired so you may need to slightly tweak this.
    va_list args;
    va_start (args, format);
    vsnprintf (buf, sizeof (buf) - 1, format, args);
    va_end (args);

    std::cout << "LogMessage: " << buf << std::endl;
}

template <class... Arguments>
void LogMessage(char const* format, Arguments... arguments)
{
    LogMessageWorker (format, std::forward<Arguments>(arguments)...);
}

void LogMessage(char const* text)
{
    LogMessageWorker ("%s", text);
}

int main(int argc, char **argv)
{
    LogMessage ("The test is starting...");

    for (int i = 0; i < 3; i++)
        LogMessage ("This is test #%d", i);

    LogMessage ("This contains the % character and still it works (%d-%d-%d-%d)");

    return 0;
}
Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37
  • A very good solution, but it does not work with VS2010... it works with VS2013... maybe I must bite the bullet to go through all the code and find the Log calls with one argument... – Jochen Kalmbach Dec 16 '14 at 09:07
  • Having two functions sounds like a good solution but it's also error-prone. Have you considered using variadic macros? You will need to work around another VC implementation quirk, as described [here](http://stackoverflow.com/questions/9183993/msvc-variadic-macro-expansion/9338429#9338429) but it could work well. – Nik Bougalis Dec 16 '14 at 09:15