在 C 中,您可以創建檢查特定型別相等性的概念:
template<typename T> concept Int = std::is_same_v<T, int>;
template<typename T> concept String = std::is_same_v<T, std::string>;
是否有可能提出一個概念來檢查任何型別的型別相等性,這樣我就可以使模板看起來像這樣:
template<ValidType<int>... Ints> void passInts(Ints... ints) {}
template<ValidType<std::string>... Strings> void passStrings(Strings... strings) {}
這樣我只需要撰寫一個概念來檢查型別是否相等。我知道我可以conjunction用于此,但我認為概念更清晰。
uj5u.com熱心網友回復:
我的意思是,你可以寫一個概念來做到這一點。或者你可以只使用std::same_as:
template<std::same_as<int>... Ints> void passInts(Ints... ints)
template<std::same_as<std::string>... Strings> void passStrings(Strings... strings)
當一個概念用于模板引數包時,它會單獨應用于包中的每個型別。
當然,這可能不能完全滿足您的需要。原因是same_as它的名字非常認真。如果您想通過轉發參考呼叫完美轉發,模板引數推導可以開始將型別推導為對T. 這不是 " same_as" T。
所以如果你想允許完美轉發,你需要一個不同的概念:similar_to. 遺憾的是,標準庫中沒有,盡管它是多么簡單和有用:
template<typename T1, typename T2>
concept similar_to = std::same_as<std::remove_cvref_t<T1>, T2>;
請注意,這假定T2沒有參考或 cv 限定詞。您可以制作一個從兩者中洗掉 cvref 的版本。
現在,您可以這樣做:
template<similar_to<int> ...Ints> void passInts(Ints && ...ints)
template<similar_to<std::string> ...Strings> void passStrings(Strings && ...strings)
現在你得到完美的轉發回來。
uj5u.com熱心網友回復:
不確定我是否完全理解您想要什么,但您可以將要檢查的型別添加為第二個模板引數:
template<typename T, typename U> concept ValidType = std::is_same_v<T, U>;
那么您的兩個示例將起作用,因為所有模板引數都將分別限制為intor std::string。
事實上,這正是std::same_as標準庫中的概念已經在做的事情。因此,只需使用它而不是ValidType獲得上面簡單變體中缺少的約束包容的額外好處。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/537516.html
標籤:C 模板C -概念
