簡體   English   中英

為什么文字運算符不能正常模板化?

[英]Why can't the literal operator be templated normally?

我目前正在研究編譯時表達式樹,並希望使用文字運算符從文字創建表達式。 由於所有文字都被允許作為表達式,我想將文字運算符模板化,例如:

template <typename T>
constexpr auto operator""_ve(T value)
{
    return value_expression(value);
}

這沒有編譯,所以我做了一些研究,發現唯一允許的模板是

template <char...> XYZ operator "" _abc();

這是為什么? 我真的必須手動指定每個重載嗎?

我真的必須手動指定每個重載嗎?

是的。

文字運算符不是通過重載解析調用的(不是真的)。 重載解析可以做一些事情,比如允許隱式轉換或其他不愉快的事情。 因為文字運算符(通常)由編譯器在編譯時生成的值上調用,所以最好確保文字運算符的作者獲得整個文字值(當然,編譯器可以提供的最好) , 不是轉換后的值。

這實際上非常重要。 考慮這樣一種情況:您想編寫一個采用整數值而不是浮點值的文字。 也就是說, 12.3_lit應該是編譯錯誤。 您的運算符簽名將采用unsigned long long ,但long double可隱式轉換為unsigned long long 因此, 12.3_lit在您不希望它是有效的時候是有效的。

現在理論上你可以通過= delete顯式地= delete浮點簽名來避免這種情況。 但是...... UDL 是在= delete並不是真正的東西的時候發明的,所以這不一定是一種選擇。

為了避免這些情況,文字運算符分派邏輯顯式查找一組特定的簽名(基於正在處理的文字類型)。 如果操作符沒有long double重載(或原始文字版本),那么在遇到12.3_lit ,系統將找不到合適的函數並生成編譯錯誤。

因為系統搜索特定的簽名而不是使用重載解析,所以文字運算符簽名(包括模板)被限制為精確且僅是文字運算符分派邏輯將搜索的簽名 不多也不少。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM