[英]Template specialization only for certain methods
我無法在我的vec2模板類中專門研究某些方法。 這是我的代碼:
#pragma once
template<typename Number>
struct vec2
{
static_assert(std::is_same<Number, int>::value
|| std::is_same<Number, float>::value
|| std::is_same<Number, double>::value,
"Type not allowed. Use <int>, <float> or <double>.");
Number x, y;
vec2();
vec2(Number x, Number y);
void add(const vec2& other);
inline Number lengthSquared() const;
/*Some other general methods like this two*/
}
我的問題是:我想這樣專門化我的length
方法:
如果模板類型為int
( vec2<int>
),則必須返回float
如果模板類型為float
( vec2<float>
),則必須返回float
如果模板類型為double
( vec2<double>
),則必須返回double
我以前像這樣專門化了我的length
方法:
struct vec2
{
/* ... */
inline Number length() const;
}
/*Outside vec2 struct, but in vec2.h*/
template<> inline int vec2<int>::length() const;
template<> inline float vec2<float>::length() const;
template<> inline double vec2<double>::length() const;
然后在我的.cpp文件中實現。 效果很好,但它只能返回相同的模板類型,而不能返回vec2<int>
的float length
。 有沒有辦法做到這一點?
您可以編寫一個幫助程序類型,該給定類型為給定矢量分量類型的length
的返回類型。
template<typename T>
struct vec_length_t {};
// Specializations:
template<>
struct vec_length_t<int> { using type = float; };
template<>
struct vec_length_t<float> { using type = float; };
template<>
struct vec_length_t<double> { using type = double; };
(或者給它一個更通用的名稱,以便在其他地方重用,例如floatify
或類似名稱)
然后像這樣使用它:
template<typename Number>
struct vec2 {
...
typename vec_length_t<Number>::type length() const;
...
};
要重用於同一類中的多種功能或用途,您當然也可以使用本地類型別名:
template<typename Number>
struct vec2 {
...
using length_t = typename vec_length_t<Number>::type;
...
length_t length() const;
...
};
這使得在函數體中使用length_t
來調用正確的std::sqrt
重載也很容易(當您要返回float
時,您可能不想使用double
重載!):
template<typename Number>
vec2<Number>::length_t vec2<Number>::length() const {
// Note that x*x+y*y is a Number, but we want a length_t:
return std::sqrt(static_cast<length_t>(x*x + y*y));
// Or, if you have lengthSquared() defined as returning a Number:
return std::sqrt(static_cast<length_t>(lengthSquared()));
}
有幾種可能的選擇:
1)使用某種形式的helper traits模板來提供長度的返回類型:
如果僅提供要存儲在模板中的類型的特殊化(int,float,double),那么您可以擺脫static_assert(盡管就潛在錯誤消息的可讀性而言,靜態斷言最有可能具有優勢) )
一個人也可以只為int提供此特征模板的專業化,並為其他所有內容提供通用版本,再加上static_assert已經可以使用相同的功能,但是要寫的專業性要少一些,但是在我看來,關於您所處理類型的知識然后將類散布在兩個地方(特征和靜態斷言)
2)如果“通用”情況(雙精度和浮點)的實現是相同的,並且只有int情形不同-可以使用is_same :)的結果使用false_type / true_type進行公共長度調用私有長度重載,更少可擴展,但不需要任何外部類型:
auto length() -> decltype(length(is_same<T, int>) { return length(is_same<T, int>); }
Number length(std::false_type) { .... }
float length(std::true_type) {....}
當然,使用C ++ 14可以擺脫decltype mambo-jambo。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.