2011-01-09 39 views
2

我想編寫一個模板化函數,根據傳入的模板類類型更改其行爲。爲此,我想確定傳入的類型。例如,這樣的事情:確定在C++中是否有相同基礎類型的別名

template <class T> 
void foo() { 
    if (T == int) { // Sadly, this sort of comparison doesn't work 
    printf("Template parameter was int\n"); 
    } else if (T == char) { 
    printf("Template parameter was char\n"); 
    } 
} 

這可能嗎?

+0

對於特定類型(如果T是int類型)或整個類型組(如果T是一個指針,或者T是T的話) '是一個整數類型,或者如果'T'是無符號的) – jalf

+0

當你在這裏調用foo時,你需要手動指定類型,因爲編譯器無法推斷出類型。 ''foo ()'或'foo ()'或'foo ()'等。這意味着'foo ()'將會輸出'Template parameter is int'這似乎是多餘的。 –

回答

2

通過使用部分專業化的力量,這可以在編譯時完成:

template<class T, class U> 
struct is_same_type 
{ 
    static const bool value = false; 
}; 
template<class T> 
struct is_same_type<T, T> 
{ 
    static const bool value = true; 
}; 

template <class T> 
void foo() 
{ 
    if (is_same_type<T, int>::value) 
    { 
     printf("Template parameter was int\n"); 
    } 
    else if (is_same_type<T, char>::value) 
    { 
     printf("Template parameter was char\n"); 
    } 
} 

在我的頭編譯,但仍應工作。

+6

爲什麼不直接專門化'foo'呢?這將消除'if ... else if ...'的需要。 –

+0

所以你想添加運行時成本的東西,知道在編譯時? –

+0

@Martin York取決於編譯器。 is_same_type ::值是一個編譯時常量,所以if可能會得到優化。但是,是的,我同意專業化foo是一個更好的主意。 –

8

這是模板專門化的目的,搜索該術語給出了大量的例子。

#include <iostream> 

template <typename T> 
void foo() 
{ 
    std::cout << "Unknown type " << typeid(T).name() << "\n"; 
} 

template<typename T> 
void fooT(T const& x) { foo<T>(); } 

template<> 
void foo<int>() 
{ printf("Template parameter was int\n"); 
} 

template<> 
void foo<char>() 
{ printf("Template parameter was char\n"); 
} 

int main() 
{ 
    fooT(std::cout); 
    fooT(5); 
    fooT('a'); 
    fooT("Look Here"); 
} 
+0

還有很多需要說的,imo。 – Puppy

0

直接使用type_info,或者更好的是typeid操作符來做到這一點。

#include <typeinfo> 
template < typename T > 
T max(T arg1, T arg2) { 
    cout << typeid(T).name() << "s compared." << endl; 
    return (arg1 > arg2 ? arg1 : arg2); 
} 
1

使用模板特化或typeid可能適合您,但您可能更喜歡模板特化,因爲它不會產生typeid的運行時成本。例如:

#include <iostream> 
#include <typeinfo> 

template <typename T> 
void foo(T arg) { 
    if (typeid(arg) == typeid(int)) std::cout << "foo<T> where T is int\n"; 
    else if (typeid(arg) == typeid(double)) std::cout << "foo<T> where T is double\n"; 
    else if (typeid(arg) == typeid(char)) std::cout << "foo<T> where T is char\n"; 
} 

template <> 
void foo<int>(int arg) { 
    std::cout << "foo<int>\n"; 
} 

int main() { 
    foo(3); // foo<int> 
    foo(3.0); // foo<T> where T is double 
    foo('c'); // foo<T> where T is char 
} 
相關問題