2015-06-09 52 views
0

我有一個AA模板與Scalar可以是實數或複數值。它有一個方法realPart它應該返回數字的實際部分。如果Scalar是實數值,則它應該返回原始標量,如果它是複雜類型,則返回.real()模板類:檢查在編譯時是否複雜

當寫

#include <complex> 
#include <iostream> 

template<class Scalar> 
class A { 
    public: 
    A (const Scalar z): 
     z_(z) 
    { 
    } 

    Scalar realPart() 
    { 
     return z_.real(); 
    } 

    private: 
    Scalar z_; 
}; 

int main() { 
    A<std::complex<double>> z0((1.0, 2.0)); 
    std::cout << z0.realPart() << std::endl; // check 

    A<double> z1(1.0); 
    std::cout << z1.realPart() << std::endl; // mööp 
} 

編譯器會在z1.realPart()抱怨,因爲double不知道.real()

在編譯時如何防範.real()

+0

你到底要帶雙到發生什麼事? –

+1

您可以爲複雜類型創建模板特化。 –

+0

@DavidHaim在'double'的情況下,只需'return z_',就像你所期望的那樣。 –

回答

2

這可以用一個簡單的is_complex特質和SFINAE來完成:

template<class T> struct is_complex : std::false_type {}; 
template<class T> struct is_complex<std::complex<T>> : std::true_type {}; 

template<class Scalar> 
class A { 
public: 
    A(const Scalar z) : z_(z) 
    { } 

    template<class S = Scalar, std::enable_if_t<is_complex<S>{}>* = nullptr> 
    Scalar realPart() 
    { 
     return z_.real(); 
    } 

    template<class S = Scalar, std::enable_if_t<!is_complex<S>{}>* = nullptr> 
    Scalar realPart() 
    { 
     return z_; 
    } 
private: 
    Scalar z_; 
}; 
+0

爲什麼需要類S模板參數?你不能用is_complex ? – Eugene

+0

@Eugene替代失敗必須發生在模板的* immediate context *內。整個類的「外層」模板不是成員函數模板的直接上下文。所以我們使用一個虛擬參數來對它進行別名。 – 0x499602D2

+0

添加'#include '和'#include '後,我得到''std :: enable_if_t'沒有被聲明。這是與GCC 5.1.1。有什麼我忘了補充嗎? –

相關問題