2016-02-01 17 views
7

我想打一個構造一類,使用任何整數類型,但符號和無符號區分。我不希望這是班級本身的模板。以下不起作用。 Visual Studio只是說沒有參數可以匹配。使符號和無符號變量可變參數的構造函數使用enable_if

class Thing{ 
public: 
    template<typename Integral> 
    Thing(
     typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      std::is_signed<Integral>::value 
      ,Integral 
     >::type num 
    ){ 
     //constructor using signed variable as input 
    } 
    template<typename Integral> 
    Thing(
     typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      !std::is_signed<Integral>::value//notice this is different 
      ,Integral 
     >::type num 
    ){ 
     //constructor using unsigned variable as input 
    } 
}; 
+1

它不工作?它在做什麼? :) – erip

+0

缺乏'public'關鍵字的說了些什麼,至少約第一個錯誤,而試圖上面的代碼中,我會得到... – skypjack

回答

5

我們需要將SFINAE移動到模板。如果我們使用

class Thing{ 
public: 
    template<typename Integral, typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      std::is_signed<Integral>::value 
      ,Integral>::type* = nullptr> // will fail if type does not exist 
    Thing(Integral i) 
//  ^use Integral type here 
    { 
     std::cout << "signed\n"; 
    } 
    template<typename Integral, typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      !std::is_signed<Integral>::value//notice this is different 
      ,Integral>::type* = nullptr> 
    Thing(Integral i) 
    { 
     std::cout << "unsigned\n"; 
    } 
}; 

int main() 
{ 
    int a = 10; 
    Thing b(a); 
    unsigned int c = 10; 
    Thing d(c); 
} 

我們得到

signed 
unsigned 

Live Example

我也有過,因爲他們private在默認情況下,使構造public

3

的問題是,該類型出現在non-deduced context,所以編譯器不能像std::is_integral<Integral>::value推斷出結論。試試這個:

#include <iostream> 
#include <type_traits> 

class Thing{ 
public: 
    template<typename Integral> 
    Thing(Integral num, 
     typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      std::is_signed<Integral>::value 
      ,Integral 
     >::type* = nullptr 
    ){ 
     std::cout << "signed\n"; 
     //constructor using signed variable as input 
    } 

    template<typename Integral> 
    Thing(Integral num, 
     typename std::enable_if< 
      std::is_integral<Integral>::value && 
      !std::is_same<Integral,bool>::value && 
      !std::is_signed<Integral>::value//notice this is different 
      ,Integral 
     >::type* = nullptr 
    ){ 
     std::cout << "unsigned\n"; 
     //constructor using unsigned variable as input 
    } 
}; 

int main() 
{ 
    int x{}; 
    unsigned int y{}; 
    Thing thing1(x); 
    Thing thing2(y); 
} 

Live on Coliru

旁註:讓你的構造public否則你不能實例化對象。

+0

你悄悄迴避指出,OP也需要使構建函數'public' :-) – AndyG

+0

@AndyG我忘了提及的確如此,但在我的代碼使他們'public';) – vsoftco

+0

個人而言,我更願意把'enable_if'模板ARGS:'模板 ::值)&& (!標準:: is_same ::值)&& (標準:: is_signed ::值),INT> ::類型= 0> 事情(T _in )'但是都是一樣的 – AndyG

相關問題