8.3.5 / cv-qualifier-seqは、非静的メンバー関数の関数型、メンバーへのポインターが参照する関数型、または関数typedef宣言の最上位関数型の一部である必要があります。関数宣言子でのcv-qualifier-seqの効果は、関数型の上にcv-qualificationを追加することと同じではありません。つまり、cv-qualified関数型を作成しません。
正しく読めば、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;
}
メンバー関数へのポインターは、同等かどうかを比較できます。エラーをトリガーするタイプのoperator==
とoperator!=
を記述する必要があります。Testable::bool_type
これらの演算子はテンプレートになり、誤った本体を持つ可能性があるため、安全なブールイディオムの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を介して安全なブールイディオムを実装する必要があることを意味します。ただし、ゼロとの比較は引き続き機能します。
非メンバー関数ルートを使用する場合は、、、も指定する必要が<
あります。>
<=
>=