2016-12-15 60 views
1

我有兩套代碼,其中第一個編譯和行爲與預期相同,但[看似是]不必要的冗長:具有類型特徵的模板元編程:爲什麼第一個代碼編譯,第二個編譯不?

template<point_type type, typename T> 
struct point2d_base { 
    std::enable_if_t<std::is_arithmetic_v<T>, T> x, y; 
    template<point_type t2 = type> 
    point2d_base(std::enable_if_t<t2 == point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
    template<point_type t2 = type> 
    explicit point2d_base(std::enable_if_t<t2 != point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
/*Some unrelated code*/ 
}; 

這是我寧願寫代碼,但是我得到很多很多的編譯錯誤,如果我不喜歡這樣寫道:

template<point_type type, typename T> 
struct point2d_base { 
    std::enable_if_t<std::is_arithmetic_v<T>, T> x, y; 
    point2d_base(std::enable_if_t<type == point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
    explicit point2d_base(std::enable_if_t<type != point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
/*Some unrelated code*/ 
}; 

以供參考,point_type是一個「枚舉類」包含三個值:genericcornercenter

我的問題是:爲什麼第一個代碼編譯,第二個沒有?

回答

1

您不能依賴您的模板類參數來使用std::enable_if。 如果要將std::enable_if用作函數,則必須使該函數成爲模板函數。 這是因爲當你的類模板被實例化時,該類的所有成員函數也會實例化。您需要一個模板成員函數來有條件地啓用或不啓用該功能。 (這是我的猜測,我認爲是正確的)

+0

是否有一個更接近我在第二個示例中編寫的代碼的正確版本,其中我不需要將'type'變量重新聲明爲別的東西? – Xirema

+0

如果你想使用'std :: enable_if',我不這麼認爲。基於您的要求的其他選項可以是模板專業化。 – MRB