Compiler warning on “Effective C++”s method to avoid duplication in const and non-const member functions

社会主义新天地 提交于 2019-12-08 06:44:44

问题


This question has been updated. Please review the code.

The following code was compiled with VC++ Nov 2012 CTP. Scott Meyers' book "Effective C++" recommend that we should use the method of to avoid duplication in const and non-const member functions. However, the following code cause a warning (level 1). Because WDK build tool treats warnings as errors, so the following code cannot be compiled successfully.

Is there other better method?

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(); 
}

回答1:


You've transposed the bodies of the two Get methods, so the compiler is correct; the const Get method is calling itself. Aren't you glad now that your build tool treats warnings as errors? :)

Swap them round:

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

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



回答2:


I believed you got it reverse. This is the non-const version which casts away constness on the const version.

See: Elegant solution to duplicate, const and non-const, getters?




回答3:


Answering the updated question. (You should have made this a new question)

In static_cast<const decltype(*this)&>(*this), *this is an lvalue of type A, so the type denoted by decltype(*this) is A& (see 7.1.6.2 [dcl.type.simple]/4).

As a result your non-const Get() function is equivalent to:

int Get()
{
    typedef A & Aref;
    // IMHO a const_cast would be the better choice here
    return static_cast<const Aref&>(*this).Get();
}

cv-qualifiers on a reference type are ignored. With reference-collapsing, your cast is ultimately equvalent to static_cast<A&>(*this), so you don't add the const you need.

So using decl_typedoes not work here. If you very badly want to use it, you'd need:

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


来源:https://stackoverflow.com/questions/15132048/compiler-warning-on-effective-cs-method-to-avoid-duplication-in-const-and-no

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!