关于“Effective C ++”方法的编译器警告,以避免const和非const成员函数中的重复

时间:2013-02-28 09:36:18

标签: c++ c++11 compiler-errors const overloading

此问题已更新。请查看代码。

以下代码是使用VC ++ 2012年11月的CTP编译的。斯科特迈耶斯'本书" 有效的C ++ "建议我们应该使用方法来避免const和非const成员函数的重复。但是,以下代码会导致警告(级别1)。因为WDK构建工具将警告视为错误,所以无法成功编译以下代码。

还有其他更好的方法吗?

struct A
{
    int n;

    A(int n)
        : n(n)
    {}

    int Get() const
    {
        return n;
    }

    int Get()
    {
        return static_cast<const decltype(*this)&>(*this).Get();
    }
};

int main()
{
    const A a(8);

    //
    // warning C4717: 'A::Get' : recursive on all control paths,
    // function will cause runtime stack overflow
    //
    a.Get(); 
}

3 个答案:

答案 0 :(得分:6)

您已经转换了两个Get方法的主体,因此编译器是正确的; const Get方法调用自身。现在您的构建工具将警告视为错误,您不高兴吗? :)

交换它们:

int& Get()
{
    return const_cast<int&>(static_cast<const A&>(*this).Get());
}

const int& Get() const
{
    return n;
}

答案 1 :(得分:4)

我相信你反过来了。这是非const版本,它会在const版本上抛弃const。

请参阅:Elegant solution to duplicate, const and non-const, getters?

答案 2 :(得分:1)

回答更新后的问题。 (你应该把它作为一个新问题)

static_cast<const decltype(*this)&>(*this)中,*thisA类型的左值,因此decltype(*this)表示的类型为A&(见7.1.6.2 [dcl。 type.simple] / 4)。

因此,非const Get()函数等同于:

int Get()
{
    typedef A & Aref;
    // IMHO a const_cast would be the better choice here
    return static_cast<const Aref&>(*this).Get();
}
忽略引用类型上的

cv-qualifiers 。使用引用折叠,您的强制转换最终与static_cast<A&>(*this)等效,因此您不需要添加所需的const。

所以使用decl_type在这里不起作用。如果你非常想要使用它,你需要:

int Get()
{
    // Made my suggested change of cast here
    return const_cast<const std::remove_reference<decltype(*this)>::type&>(*this).Get();
}