2012-10-29 23 views
2

我正在提供一個支持功能欄()的庫。當你傳入一個標量值(比如double,int,whatever)時,它的作用與傳遞非標量值的東西(在所有預期的情況下是用戶定義的類型)不同。所以我寫了這樣的代碼:非內置模板,內置過載模塊

#include <iostream> 

class Foo 
{ 
public: 
    template <class T> void bar(T const &rhs) { std::cout << "T" << std::endl; } 
    void bar(double rhs) { std::cout << "double" << std::endl; } 
}; 

int main() 
{ 
    Foo foo; 
    foo.bar(4); 
} 

的問題,這是對主),第二行(。該代碼的結果是「T」的輸出。編譯器比Bar(double)的調用更喜歡模板,我假設這是因爲參數是一個int,它寧願投射到int const &(因爲const &可以引用r值)。

我的問題是「有沒有一種方法可以支持每個標量值而不需要明確地調用它們?」我真的不想調出所有可能的類型,因爲......呃...有很多。我將不得不涵蓋從char到long的所有內容,包括volatile和unsigned的所有組合,等等。

我知道,只是將4改爲4.0的作品,但這是針對圖書館的公共接口,並且要求用戶輸入4.0而不是4只是骯髒。

+1

你真的想要所有的標量類型,包括指針類型嗎?如果不是,你正在尋找的單詞是* arithmetic *類型。 – Xeo

+0

好點,我其實只是想要每個C++定義的算術類型;我的術語「標量」在我正在研究的圖書館中更有意義。 – Shirik

回答

4

是,與性狀:

#include <type_traits> 
#include <iostream> 

class Foo 
{ 
public: 
    template <class T> 
    typename std::enable_if<!std::is_scalar<T>::value, void>::type bar(T const & rhs) 
    { 
     std::cout << "T" << std::endl; 
    } 

    void bar(double rhs) 
    { 
     std::cout << "double" << std::endl; 
    } 
}; 

有類型的六個基本類別:標量,函數,數組,類,工會和引用。和void。他們每個人都有相應的特質。 See here for more details.

+0

這是一個很好的答案,也是我愛C++ 11的原因之一。不幸的是,我用於這個項目的編譯器不支持C++ 11(並且升級它不是一個選項)。它看起來像boost有一個is_scalar雖然,所以我會考慮看看,如果這將工作。 – Shirik

+0

我認爲基於'is_arithmetic'和'is_enum'的自定義特徵在這裏更合適。或者甚至可能只是'is_arithmetic'。 – Xeo

+0

您可以查看手冊中的[「可能的實現」](http://en.cppreference.com/w/cpp/types/is_scalar),但其中一些特性需要編譯器支持,恐怕。 –