考慮以下示例,該示例嘗試將 a 傳遞std::array給函式。自然不會考慮“轉換”,但是是否有任何解決方法而不必明確?特別是如果該類已經提供了必要的屬性(value_type 等)。
template <typename T, size_t N>
struct Array_t
{
using value_type = T;
using size_type = size_t;
std::array<T, N> Internal{};
constexpr operator auto() { return Internal; }
};
template <typename T, size_t N> constexpr bool Test(std::array<T, N> Input)
{
return Input.size() == 32;
}
constexpr std::array<uint8_t, 32> OK1 = Array_t<uint8_t, 32>();
constexpr auto OK2 = Test((std::array<uint8_t, 32>)Array_t<uint8_t, 32>{});
constexpr auto OK3 = Test(Array_t<uint8_t, 32>().Internal);
// could not deduce template argument for 'std::array<_Ty,_Size>'
// from 'Array_t<uint8_t,32>'
constexpr auto FAIL = Test(Array_t<uint8_t, 32>{});
澄清一下,一種解決方法,以便可以將 Array_t 結構直接傳遞給任何期望 std::array 的函式。沒有強制轉換,沒有幫助器/轉換函式,只是讓編譯器了解結構是可轉換的某種方式。可能以與 CTAD 類似的方式。
uj5u.com熱心網友回復:
模板扣除從不考慮(用戶定義的)轉換。鑒于您的:
template <typename T, size_t N>
constexpr bool Test(std::array<T, N> Input);
如果您在代碼中看到 ,Test(x)那么只有x在特定型別std::array或繼承(公開且明確)的情況下才有效。
如果你想讓這個作業,你有幾個不同的選擇(按照我個人的偏好順序):
您可以制作
Test更廣泛的函式模板,接受它實際可以使用的任何東西,而不僅僅是專門的std::array<T, N>. 鑒于您說“特別是如果該類已經提供了必要的屬性(value_type 等)”,這表明您想要的Test并不是專門的std::array. 因此,您應該弄清楚這些實際屬性是什么,并撰寫一個適當約束的函式模板。例如,是否ranges::contiguous_range足夠或者您實際上需要編譯時大小?你甚至需要鄰接嗎?等等。您可以在呼叫端顯式地將您的轉換
Array_t為 a 。std::array如果你給轉換函式一個名字,這會更好,所以你可以寫類似的東西obj.to_array()而不是static_cast<std::array<T, N>>(obj)(這既要長得多,又要讓引數正確更煩人)。您可以顯式地為 提供必要的模板引數
Test,例如Test<uint8_t, 32>(obj)- 這避免了推斷T和N,現在您只有一個接受 a 的普通函式std::array<uint8_t, 32>,因此轉換作業得很好。請注意,您必須同時提供,是Test<uint8_t>(obj)不夠的。您可以
Array_t<T, N>從繼承std::array<T, N>,而不僅僅是轉換為它。這可以立即奏效。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/428005.html
上一篇:模板引數中參考型別的相等性
