必须明确解析C++内联基类方法?

Ion*_*ham 3 c++ inheritance inline clang c++11

我的类层次结构中的继承和方法解析存在一个奇怪的问题.该代码正在使用clang ++ 5.0进行编译-O0.我有两个类,所以:

class PrintBase
{
protected:
    static wstring_convert<codecvt_utf8<wchar_t>> sConverter;

public:
    virtual void PrintChar(wchar_t ch) = 0;
    inline  void PrintChar(char ch)
    {
        PrintChar(sConverter.from_bytes(ch)[0]);
    }

    virtual void PrintString(const wstring& str) = 0;
    inline  void PrintString(const string& str)
    {
        PrintString(sConverter.from_bytes(str));
    }
};

class Print: public PrintBase
{
public:
    virtual void PrintChar(wchar_t ch) override;
    virtual void PrintString(const wstring& str) override;
};

void Print::PrintChar(wchar_t ch)
{
    // do stuff
}

void Print::PrintString(const wstring& str)
{
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

如果我构造一个Print实例Print* pnt = new Print();pnt->PrintChar('c');正确调用它,则调用内联基类方法,进行转换,然后在派生类中正确调用已实现的虚拟覆盖.

如果我打电话pnt->PrintString("test");pnt->PrintString(string("test"));pnt->PrintString(someString);我的错误:

No viable conversion from 'basic_string<char, char_traits<char>, allocator<char>>' to 'const basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>'
Run Code Online (Sandbox Code Playgroud)

...对"from"类型的常量有一些变化.呼叫pnt->PrintString(L"test");等将按预期工作.我可以强制它调用内联字符串和函数pnt->PrintBase::PrintString("test");

为什么它能够正确解析并调用基类中的内联char方法,但是如果没有显式解析范围,则无法对字符串和方法执行此操作?

Rei*_*ica 5

您拥有的设置是隐藏其他继承重载的重写函数的典型示例.

在派生类中重写函数时,该重写函数会隐藏基类中的所有其他重载.选择名称后会出现重载PrintString决策,所以一旦确定要引用Print::PrintString,它就永远不会考虑PrintBase::PrintString,即使前者不接受所提供的参数而后者也会接受.

最直接的方法是使用声明将继承但未重写的名称引入派生类using:

class Print: public PrintBase
{
public:
    virtual void PrintChar(wchar_t ch) override;
    using PrintBase::PrintChar;

    virtual void PrintString(const wstring& str) override;
    using PrintBase::PrintString;
};
Run Code Online (Sandbox Code Playgroud)

我不相信PrintChar('x')通过Print对象调用实际上调用内联重载.它真正做的是wchar_tchar你传入中初始化.它是否可能与内联版本在你的情况下做同样的事情?