2013-12-23 42 views
9

我似乎回想起幾個可靠的來源(即委員會成員在非官方渠道發言)聽到模糊的評論,C型通用表達式不會被添加到C++,因爲他們不可能。爲什麼C類型的泛型表達式不能與C++兼容?

據我所知,與C++模板和重載相比,類型泛型表達式非常有限,但是沒有必要將定義爲特殊情況的交互潛力。

類型泛型表達式由控制表達式和類型與子表達式之間的一系列「關聯」組成。根據控制表達式的靜態類型和爲子表達式列出的類型選擇一個子表達式,並將其替換爲TGE。匹配基於C型概念的類型兼容性,據我所知可以等同於在單定義規則(ODR)下具有extern鏈接的類型的C++身份。

如果一個派生類控件表達式在C++中選擇一個基類關聯,但由於C沒有繼承,所以交叉兼容性不需要這樣的細節。無論如何,這被認爲是一個絆腳石?至於更具體的細節,C11已經規定保留所選子表達式的值類別(左值),並且似乎要求TGE是一個常數表達式(任何類別的)作爲它的所有操作數,包括控制表達式。這可能是C語言的缺陷。在任何情況下,C++ 14都會根據可能被評估的內容定義常量表達式,並且TGE規範已經說過,未選擇的子表達式是未評估的。

問題是,TGE的操作原理似乎很簡單,以後可以移植而不會造成麻煩。

至於爲什麼 C++ TGE的將是有益的,除了最大限度地提高C和C++的交集,它們可以被用來基本上實現static_if,SANS極具爭議的條件申報功能。我不是static_if的支持者,但「有這個。」

template< typename t > 
void f(t q) { 
    auto is_big = _Generic(std::integral_constant< bool, sizeof q >= 4 >(), 
     std::true_type: std::string("whatta whopper"), 
     std::false_type: "no big deal" 
    ); 
    auto message = _Generic(t, double: "double", int: 42, default: t); 
    std::cout << message << " " << is_big << '\n'; 
} 
+0

也許負責解決通用問題的東西必須先找出能夠指出類是如何工作的。所以你不能泛化類,因此你將會擁有一個只適用於某些類型的特性。 – leewz

+1

@leewangzhong那麼,它的工作方式與C相同。它可以適用於所有類型,只是不瞭解繼承。 – Potatoswatter

+0

我的意思是,也許C++類型在泛型解析時無法識別。 – leewz

回答

1

「不可能」可能太強大了。 「不確定是否可能」更有可能。

如果要將此功能添加到C++中,應該完全指定它,包括與現有C++功能的所有交互,其中很多都沒有考慮到_Generic。例如。 C中不存在typeid,但應該用C++工作。你能用_Generic的表示作爲constexpr嗎?作爲模板參數?這是一個lvalue?你可以把它的地址和分配給一個函數指針,並獲得重載解析?你能做模板論證扣除嗎?你能和auto一起使用嗎?等等

另一個複雜因素是_Generic的主要用例是宏的,它對C++命名空間不起作用。 tgmathacos示例就是一個明顯的例子。 C++已經禁止了C的標準宏,並要求它們是函數,但這不適用於tgmath.h

+2

這些聽起來更像是刻度線,需要檢查是否有任何交互。這個想法是選擇一個子表達式並替換整個表達式。因此,似乎沒有與您提到的任何事物進行互動的空間。至於'tgmath'宏,它們自C++ 98以來已經被超載集取代。 – Potatoswatter