0

I have this minimal testcase:

#include <string>
#include <iostream>
#include <boost/format.hpp>

class LogInterface
{
public:
    virtual void log(int level, std::string message) const = 0;

    virtual void log(int level, boost::format format) const
    {
        log(level, format.str());
    }

protected:
    const int TRACE = 60;
    const int DEBUG = 50;
    const int INFO  = 40;
    const int WARN  = 30;
    const int ERROR = 20;
    const int FATAL = 10;
};

class Test : public LogInterface
{
public:
    Test()
    {
        log(INFO, "hello");
        log(INFO, boost::format("hello %s") % "world");
    }

    virtual void log(int level, std::string message) const override
    {
        std::cout << "LOGGER: " << message << std::endl;
    }
};

int main()
{
    Test test;
    return 0;
}

The method void LogInterface::log(int level, boost::format format) const is a convenience overload to directly pass a boost::format to LogInterface::log.

The problem is that it is not resolved in Test::Test(), giving this error:

logger_test.cpp:30:19: error: no viable conversion from 'boost::basic_format<char, std::__1::char_traits<char>, std::__1::allocator<char> >' to
      'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >')
        log(INFO, boost::format("hello %s") % "world");
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../include/c++/v1/string:1349:5: note: candidate constructor not viable: no known conversion from 'boost::basic_format<char,
      std::__1::char_traits<char>, std::__1::allocator<char> >' to 'const std::__1::basic_string<char> &' for 1st argument
    basic_string(const basic_string& __str);
    ^
/usr/bin/../include/c++/v1/string:1354:5: note: candidate constructor not viable: no known conversion from 'boost::basic_format<char,
      std::__1::char_traits<char>, std::__1::allocator<char> >' to 'std::__1::basic_string<char> &&' for 1st argument
    basic_string(basic_string&& __str)
    ^
/usr/bin/../include/c++/v1/string:1364:31: note: candidate constructor not viable: no known conversion from
      'boost::basic_format<char, std::__1::char_traits<char>, std::__1::allocator<char> >' to 'const value_type *' (aka 'const char *') for 1st argument
    _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);
                              ^
/usr/bin/../include/c++/v1/string:1385:5: note: candidate constructor not viable: no known conversion from 'boost::basic_format<char,
      std::__1::char_traits<char>, std::__1::allocator<char> >' to 'initializer_list<value_type>' (aka 'initializer_list<char>') for 1st argument
    basic_string(initializer_list<value_type> __il);
    ^
logger_test.cpp:33:45: note: passing argument to parameter 'message' here
    virtual void log(int level, std::string message) const override
                                            ^
1 error generated.
fferri
  • 18,285
  • 5
  • 46
  • 95
  • To override a method, you must have the exact same parameters type – James Maa Sep 19 '17 at 19:22
  • 1
    He does.. the override is for the pure virtual function log(int, std::string) const – Rob Sep 19 '17 at 19:24
  • I suspect there is some templating magic going on behind the boost::format stuff that will require some templating on your part or something else.. maybe look at these does it make sense to you? https://stackoverflow.com/questions/18347957/a-convenient-logging-statement-for-c-using-boostformat and https://stackoverflow.com/questions/7791299/use-boostfunction-as-function-argument – Rob Sep 19 '17 at 19:39
  • adding `using LogInterface::log;` fixed it, so I confirm it is a duplicate of the marked question. (it is a feature of C++ of which I've never known about) – fferri Sep 19 '17 at 19:49

0 Answers0