2011-02-16 82 views
0

是否有可能在編譯時反映函數參數的類型?確定參數的類型

這樣

int b = add(3, 6) 

將導致模板實例中的

int add(int a, int b) { return a + b } 

出來的一些形式。然而聲明函數模板

A add(A a, B b) { return a + b } 

我不知道這對模板來說是可能的,但它們似乎並不適用於大量的元編程。

+0

在問題中缺少分號,答案無處不在。 – aschepler 2011-02-16 22:11:53

+0

最後一項陳述並非如此。 Boost甚至還有一個完整的模板元編程庫。對於元編程來說,模板非常棒。 – Xeo 2011-02-16 22:17:13

回答

0

模板做他們的魔法在編譯的時候,但是這似乎是相當充足什麼你問:

template <class T> 
T add(T a, T b) { return a + b; } 

它得到更復雜一點,當兩個可能不匹配,所以(例如),您可以將int添加到double並獲得double結果。目前的標準並不真的支持;用C++ 0x你可以查看autodecltype這樣的任務。

雖然Boost typeof通常會做這項工作。

3
template<typename T> 
T add(T a, T b) { return a + b; } 

然後你就可以與任何內置類型(是int,short,雙,浮法,等)調用此方法,它將實例化功能add在編譯時,根據所使用的類型。

請注意,如果你分成頭/來源這一點,你就會有麻煩:

add.h:

template<typename T> 
T add(T a, T b); 

add.cpp:

template<typename T> 
T add(T a, T b) { return a + b; } 

main.cpp中:

#include "add.h" 

int a = 3; 
int b = 5; 
int i = add(a, b); 

當您嘗試c省略這個,它會在鏈接時失敗。這是爲什麼。

編譯add.obj實例化add模板方法 - 因爲它從來沒有在add.cpp調用。編譯main.obj實例化函數聲明 - 但不是函數體。因此在鏈接時,它將無法找到add方法的定義。

簡單的解決辦法是乾脆把整個模板函數在頭:

add.h:

template<typename T> 
T add(T a, T b) { return a + b; } 

,然後你甚至都不需要add.cpp檔案。

3

這不是你要問的嗎?

template <typename A, typename B> 
A add(A a, B b) { return a + b; } 

這幾乎不是「重元編程」。

1

這正是模板所做的事情。

template <typename T> 
inline T add(T a, T b) { return a + b; } 

允許兩種不同的類型有點棘手,但也有可能。

1

如果你打算使用任何比你想簡單類型其他(在頭文件):

template <typename A> 
inline A add(const A& a, const A& b) { return a + b; } 

注意「內聯」。

正如其他人所指出的,混合類型的問題是如何從參數類型中確定返回類型。假設我們堅持簡單的類型並且有:

template inline A add(A a,B b){return a + b; }

那麼這個失敗(可能只有一個警告):

double d = add(1, 1.5); // Sets d to 2.0 

所以,你必須做一些工作。例如:

template<class A, class B> 
struct Promote 
{ 
}; 

template<class A> 
struct Promote<A,A> 
{ 
    typedef A Type; 
}; 

template<> 
struct Promote<int, double> 
{ 
    typedef double Type; 
}; 

template<> 
struct Promote<double, int> 
{ 
    typedef double Type; 
}; 

add函數變爲:

template<class A, class B> 
inline typename Promote<A,B>::Type add(A a, B b) 
{ 
    return a + b; 
} 

這一切都爲你所做的就是確保返回類型是一個指定將一對給定類型。即使對於複雜類型也是如此。