常量正确性和安全bool习惯用法



我还有一个关于安全bool习惯用法的问题:

typedef void (Testable::*bool_type)() const;             // const necessary?
void this_type_does_not_support_comparisons() const {}   // const necessary?
operator bool_type() const
{
    return ok_ ? &Testable::this_type_does_not_support_comparisons : 0;
}

为什么bool_type(类型定义)和this_type_does_not_support_comparisonsconst ?实际上没有人应该通过返回指针调用成员函数,对吧?这里需要const吗?否则operator bool_type(成员函数)会违反常量正确性吗?

"安全bool习语"是对这个问题的技术回答:"我想要一辆既是跑车又是拖拉机的车,也许还有一艘船"。实用的答案不是技术的答案& help;

也就是说,它解决的问题只是给出一个可转换为bool的结果,而不是其他任何东西(否则类的实例可以作为实际参数传递,例如,形式参数是int)。数据指针可以转换为void*。函数指针不是,至少在c++标准中是正式的(Posix是另一回事,也要实践)。

使用成员函数指针可以防止意外调用该函数,因为指针来自安全bool操作符。

const对它有一些限制,但如果命运让某人犯了最多的愚蠢错误,那个人可能仍然会设法调用什么都不做的函数。而不是const 我想我只是让它有一个私有类型的参数,在其他代码不能提供这样的参数,然后它不必是一个愚蠢的成员函数类型了。

可以像这样:

#include <stdio.h>
class Foo
{
private:
    enum PrivateArg {};
    typedef void (*SafeBool)( PrivateArg );
    static void safeTrue( PrivateArg ) {}
    bool    state_;
public:
    Foo( bool state ): state_( state ) {}
    operator SafeBool () const
    { return (state_? &safeTrue : 0); }
};
int main()
{
    if( Foo( true ) ) { printf( "truen" ); }
    if( Foo( false ) ) { printf( "falsen" ); } // No output.
    //int const x1 = Foo( false );        // No compilado!
    //void* const x2 = Foo( false );      // No compilado!
}

当然,实际的答案是这样的:

#include <stdio.h>
class Foo
{
private:
    bool    isEmpty_;
public:
    Foo( bool asInitiallyEmpty )
        : isEmpty_( asInitiallyEmpty )
    {}
    bool isEmpty() const { return isEmpty_; }
};
int main()
{
    if( Foo( true ).isEmpty() ) { printf( "truen" ); }
    if( Foo( false ).isEmpty() ) { printf( "falsen" ); } // No output.
    //bool const x0 = Foo( false );       // No compilado!
    //int const x1 = Foo( false );        // No compilado!
    //void* const x2 = Foo( false );      // No compilado!
}
关于

总结。提问:

  • 为什么bool_type (typedef)和this_type_does_not_support_comparison是const?

有人不太明白他们写了什么。或者也许他们想要限制调用的能力。但是,这是相当无用的措施。

  • 没有人应该通过返回指针调用成员函数,对吧?

.

    这里const是必需的吗?

    operator bool_type(成员函数)是否违反const-正确性?

干杯,hth。

8.3.5/A cv-qualifier-seq只能是for的函数类型的一部分非静态成员函数,指针指向的函数类型成员引用,或函数typedef的顶级函数类型声明。函数声明符中cv-qualifier-seq的效果是不是和在功能上面加上cv-qualification不一样类型,也就是说,它不创建一个cv限定的函数类型。

如果我没看错的话,可以在const成员函数中返回指向非const成员的指针。只是不能用非const对象调用它。

禁止调用的一种方法是:

private:
    struct private_ 
    {
        void this_type_does_not_support_comparisons() {}
    };
public:
    typedef void (private_::*bool_type)() const;
    operator bool_type() const
    {
        return ok_ ? &private_::this_type_does_not_support_comparisons : 0;
    }

指向成员函数的指针仍然可以比较是否相等。您必须为触发错误的Testable::bool_type类型编写operator==operator!=。使用安全bool习惯用法的CRTP形式更容易,因为这些操作符成为模板,因此可能具有错误的主体。

的例子:

template <typename T>
class safe_bool_concept
{
    // Implementation detail of safe bool
protected:
    ~safe_bool_concept() {}
public:
    operator safe_bool() const
    {
        return static_cast<const T*>(this)->is_null() ? ...;
    }
};
struct Foo : safe_bool_concept<Foo>
{
    ...
private:
    friend class safe_bool_concept<Foo>;
    bool is_null() const { ... }
};

那么你可以这样做(对!=做同样的事情):

template <typename T>
void operator==(const safe_bool_concept<T>& x, const safe_bool_concept<T>&)
{
    x.some_private_member(); // invalid, but won't be generated
                             // unless safe_bool classes are compared
}

这意味着如果您想禁止比较,则应该通过CRTP实现安全bool习惯用法。然而,与零的比较仍然有效。

如果您选择非成员函数路线,您还必须提供<, >, <=>=

最新更新