1

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

以下代码使用 VC++ Nov 2012 CTP 编译。Scott Meyers 的《Effective C++》一书建议我们应该使用 的方法来避免 const 和 non-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(); 
}
4

3 回答 3

6

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

交换它们:

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

const int& Get() const
{
    return n;
}
于 2013-02-28T09:42:40.970 回答
4

我相信你把它弄反了。这是非常量版本,它抛弃了 const 版本的 constness。

请参阅:重复、const 和 non-const、getter 的优雅解决方案?

于 2013-02-28T09:43:05.367 回答
1

回答更新的问题。(您应该将此作为一个新问题)

In static_cast<const decltype(*this)&>(*this),*this是 type 的左值A,所以表示的类型decltype(*this)A&(参见 7.1.6.2 [dcl.type.simple]/4)。

因此,您的非常量Get()函数相当于:

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

引用类型上的cv 限定符被忽略。使用引用折叠,您的演员最终等同于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();
}
于 2013-02-28T11:50:50.540 回答