[英]Specialize template member function with already-deduced template parameter
我想基於已經推導出的結構模板參數的類型特征來專門化模板結構的成員函數。 當模板參數簽名時,我想要一個版本的函數,而在未簽名模板時,我想要另一個版本。 不知道如何去做。
結構很簡單。 它代表着一個大小-毫無疑問,它被寫了一千遍了。 我猜這是一個可以用於所有類型的簡單版本:
template<class T>
struct Size
{
T cx;
T cy;
// ... a bunch of functions you might expect.
// normalize function -- avoid negative sizes. make sure size is at LEAST 0, 0
void normalize()
{
cx = std::min(cx, 0);
cy = std::min(cy, 0);
}
};
但是,當然,對於無符號類型,該處理功能毫無意義。 我想讓這些類型成為空手。
有一秒鍾,我想我可能會嘗試將enable_if與return類型一起使用。
typename std::enable_if<std::is_signed<T>::value, Size&>::type
normalize()
{
cx = std::max(cx, 0);
cy = std::max(cy, 0);
return *this;
}
typename std::enable_if<std::is_unsigned<T>::value, Size&>::type
normalize()
{
return *this;
}
但這是行不通的,因為(據我所知)是因為在成員函數的位置已經推導出模板“ T”,並且無法使用SFINAE。 如果我做錯了,請糾正我。
所以我想我可以這樣寫true_type和false_type重載:
void normalize(std::true_type)
{
// Ensure signed types are at least zero.
cx = std::max(cx, 0);
cy = std::max(cy, 0);
}
void normalize(std::false_type)
{
// do nothing for unsigned types
}
void normalize()
{
// Call overload based on type.
normalize(std::is_signed<T>::type());
}
但是那些似乎毫無意義地構造了std::integral_constant<bool>
。 那冒犯了我的效率感。 如果這是一個更復雜的示例,則它甚至可能會影響性能。
因此,相反,我可以類似地編寫如下的成員模板函數:
template <typename T>
void normalizeT()
{ }
template<>
void normalizeT<std::true_type>()
{
cx = std::max(cx, 0);
cy = std::max(cy, 0);
}
void normalize()
{
normalizeT<std::is_signed<T>::type>();
}
我猜還有其他方法。 但是我感覺好像我缺少明顯的東西。 我總是喜歡花時間將這些東西簡化為最簡單,最清晰,最可靠的版本。
我意識到這不是一個非常復雜的“問題”。 就像我說的那樣,我已經可以使代碼正常工作了,但是我正在尋找更一般的課程-了解和認識所涉及的“模式”,因為這是我經常遇到的那種情況。
因此,鑒於這些目標,是否有一種方法可以更簡潔或更可靠地編寫此代碼?
不要手動優化(使用模板)。 只是讓編譯器在std::max
上進行優化(注意:您應該使用std::max
來“避免出現負數”)
為了澄清或者如果normalize
實際上更復雜,您可以執行以下操作:
void normalize()
{
if(std::is_signed<T>::value) {
cx = std::max(cx, 0);
cy = std::max(cy, 0);
// ...
}
}
除非您可能正在為嵌入式硬實時系統編寫程序,否則在過早優化的要點下,這是直截了當的。 即使看起來不太理想,您也應該編寫簡單易懂的代碼。 編譯器甚至可能足夠聰明,可以為您優化對std::max
的調用! 如果程序的性能可以接受,那么一切都不會丟失:您編寫了一次代碼,一切都很好。 如果性能成為問題,則應該概述瓶頸,而不是猜測瓶頸,只有當它表明對未簽名類型進行規范化是您的問題所在(我無法想象這是真的)時,您才考慮將其專門化為沒事
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.