2014-01-25 166 views
4

我回答this question,有關用戶定義的轉換到bool以及如何的話題比較禁用其他轉換:隱式轉換爲布爾值,並與布爾文字

struct foo 
{ 
    operator bool() const //Explicit overload for bool 
    { 
     return true; 
    } 

    template<typename T> 
    operator T() const = delete; //Everithing which is not a bool (Everithing which 
           //does not fit in the explicit overload) would 
           //resolve to this operator and will fail. 
}; 


int main() 
{ 
    foo f; 

    bool b = f; //OK 
    int i = f; //ERROR 
    char c = f; //ERROR 
    etc... 
} 

後來,OP問我爲什麼喜歡if(f == true)條件語句失敗(凡ffoo我試圖通過我自己和我吃驚,因爲與布爾文字是比較導致轉換到int(這是禁用的),而不是bool

int main() 
{ 
    foo f; 

    if(f); //OK, converts to bool 
    if(f == true); //ERROR: Conversion to int, which has been disabled 
} 

prog.cpp:20:12: error: use of deleted function ‘foo::operator T() const [with T = int]’ if(f == true);
..............................................................................................................................................^

我的問題是:是布爾文字定義爲整數(如常見的C宏#define true 1 #define false 0),如果沒有,爲什麼比較鉛爲int的轉換,而不是bool

我在啓用C++ 11的情況下使用GCC4.8.1(-std=C++11)。

Here是ideone行爲的一個例子。

+1

注有一個在之間的相關例子的有趣差異並[g ++ 4.8.1](HTTP://coliru.stacked- [CWG 954](http:// www。com/cn/b2865b8fea3021b4)和[clang ++ 3.5](http://coliru.stacked-crooked.com/a/cc3c7a74ee58d588) – dyp

+1

這可能是標準中的缺陷, //www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#954)(open issue),特別是註釋*「有些實現明確地選擇了int類型候選。被調整來選擇L和R是相同類型的候選人?「*(這是我答案中缺失的部分) – dyp

回答

2

由於foo是類類型,特殊規則使用不是專門爲該類類型定義的操作時,適用,見[over.built]/12

For every pair of promoted arithmetic types L and R , there exist candidate operator functions of the form

LR operator*(L, R); 
LR operator/(L, R); 
LR operator+(L, R); 
LR operator-(L, R); 
bool operator<(L, R); 
bool operator>(L, R); 
bool operator<=(L, R); 
bool operator>=(L, R); 
bool operator==(L, R); 
bool operator!=(L, R); 

where LR is the result of the usual arithmetic conversions between types L and R .

不是使用術語提升的算術類型:這需要bool的促銷。

bool被提升到int,見[conv.prom]/6(積分促銷)

A prvalue of type bool can be converted to a prvalue of type int , with false becoming zero and true becoming one.


所以有形式的候選函數

common_type<L,int> operator==(L, int); 

其中L是一種推廣的算術類型。然而,有許多人,例如

common_type<int  , int> operator==(int  , int); 
common_type<long  , int> operator==(long  , int); 
common_type<long long, int> operator==(long long, int); 

每個這些都需要從foo到促進類型的用戶定義的轉換。我不清楚爲什麼這不是含糊不清的,因爲foo可以轉換爲其中的任何一個。這在開放問題CWG 954中也有描述。

如果存在多個非模板轉換函數,則g++4.8.1clang++3.5會報告此含糊性。 (應當指出的是,鐺可能有一個錯誤在這裏,看到this example工作正常使用g ++ 4.8.1。)


然而,沒有形式

common_type<bool, int> operator==(bool, int); 

候選如bool而不是推廣的算術類型。因此,從foobool轉換將被選擇用於表達

foo x; 
x == true 
+0

我想,答案並不完整。還有一塊失蹤。 – dyp

+0

我已經注意到了。我在等待:) – Manu343726

+0

@ Manu343726這篇文章缺失的是一些聲明,說類類型確實需要轉換爲與提升的「bool」相同的類型。它可能有點微妙,例如內置的'operator =='需要在左側和右側有相同的類型。 – dyp

0

類型bool是而不是#在C++中定義。我認爲比較提升到int並且需要int轉換。

+0

那就是我的想法,我知道bool文字不是'#define'd。只是這種行爲讓我感到驚訝。任何人都有提到標準的說法? – Manu343726

+0

將bool轉換爲int來進行比較。我沒有參考標準(需要下載,嗯......),但我非常確定,bool => int結合缺少類foo的int轉換是錯誤的根源。 – rholmes

0

讓我們在這裏做一個簡單的測試:

template <typename T> 
struct OutputType; 

int main() 
{ 
    OutputType<decltype(true)> a; 
} 

ATLEAST ideone這裏輸出的是truebool類型:http://ideone.com/Gm653T

但是:

The type bool can be converted to int with the value false becoming ​0​ and true becoming 1.

來源:cppreference

一個第二我的猜測是,正是這樣的促銷發生在這裏