8.3.5/A CV-限定符-SEQ應僅是功能類型的一部分 一個非靜態成員函數中,向其中一個指針 構件是指功能類型,或頂層功能型一個函數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!=
。使用安全布爾方式的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如果你想禁止的比較來實現。然而,比較爲零仍然有效。
如果你走非會員功能路線,你將不得不提供<
,>
,<=
和>=
。
我敢打賭,'const'是沒有必要的。函數的主體也不是,因爲無論如何你都不應該調用函數。 –
@Alex:但是沒有body的成員函數沒有地址,對吧?至少在沒有VC10的機構的情況下,它是無法編譯的。 – fredoverflow
嗯你是對的。我剛剛檢查過我的VS2005當前項目中的'safe_bool'模板,它有一個主體。它也有'const'。 –