2016-12-07 48 views
0

我正在使用enable_if語句來刪除可能的方法。enable_if如何用於刪除代碼

#include "gmpxx.h" 
#include <iostream> 

template <typename T> 
struct is_ring_field { 
}; 

template <> 
struct is_ring_field<int> { 
    static const bool value = false; 
}; 

template <> 
struct is_ring_field<mpq_class> { 
    static const bool value = true; 
}; 

template<typename T> 
std::enable_if<is_ring_field<T>::value,int> RankMat(T const& Input) 
{ 
    return 10; 
} 

template<typename T> 
std::enable_if<(not is_ring_field<T>::value),int> RankMat(T const& Input) 
{ 
    return 20; 
} 

int main() 
{ 
    int M1=10; 
    mpq_class M2=3; 
    std::cerr << "FICT rank(M1)=" << RankMat(M1) << "\n"; 
    std::cerr << "FICT rank(M2)=" << RankMat(M2) << "\n"; 
} 

最終目標是讓方法根據輸入上的代數數據類型而變化。對於其他特性它爲我工作,但不是這一個。在這種情況下,編譯器奇怪地說該調用是不明確的,換言之,std :: enable_if失敗。

+1

看看'RankMat'的兩個重載。過載的哪些部分有所不同?該部分可以作爲函數的唯一部分,它不同於一個有效的重載? – NathanOliver

+2

你不忘記'typename std :: enable_if <*,*> :: type'? –

+0

是的,我在寫完信息後發現,對此感到抱歉。來自clang ++和g ++的消息都沒有幫助。 –

回答

-1

你剛把它放在錯誤的位置。 嘗試此:

template<typename T> 
int RankMat(T const& Input, typename std::enable_if<is_ring_field<T>::value,T>::type* = 0) 
{ 
     return 10; 
} 

template<typename T> 
int RankMat(T const& Input, typename std::enable_if<(not is_ring_field<T>::value),T>::type* = 0) 
{ 
     return 20; 
} 

或該:

template<typename T, typename TT = is_ring_field<T>> 
int RankMat(T const& Input) 
{ 
     return TT::value ? 10 : 20; 
} 
+0

實際上,這不是允許在sfinae中產生軟錯誤的唯一上下文...參見[this](http://melpon.org/wandbox/permlink/7MK1lLnULUVp04JY)和[this](http://melpon.org/ wandbox/permlink/SlFEgbxo6ZzxDATO)。你提出的那個實際上是可用的,因爲在函數模板參數不允許被默認之前,它是從C++ 11開始的... –

+0

沒錯。快速回答是一個壞主意。我給了錯誤的信息。這對我來說是一個教訓。 –

+0

我沒有評論給你一個教訓,只是爲了讓你改善你的答案... –

2
std::enable_if<>

是一個有效的類型;你需要使用它的type成員SFINAE:

template<typename T> 
typename std::enable_if<is_ring_field<T>::value,int>::type RankMat(T const& Input) 
{ 
    return 10; 
} 

template<typename T> 
typename std::enable_if<(not is_ring_field<T>::value),int>::type RankMat(T const& Input) 
{ 
    return 20; 
}