簡體   English   中英

模板專門化僅適用於某些方法

[英]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方法:
如果模板類型為intvec2<int> ),則必須返回float
如果模板類型為floatvec2<float> ),則必須返回float
如果模板類型為doublevec2<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.

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