2010-09-30 54 views
2
// InternalTemplate.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 

template<class T> 
struct LeftSide 
{ 
static void insert(T*& newLink, T*& parent) 
{ 
    parent->getLeft() = newLink; 
    newLink->parent = newLink; 
} 
}; 

template<class T> 
struct Link 
{ 
T* parent_; 
T* left_; 
T* right_; 
T*& getParent()const 
{ 
    return parent_; 
} 
template<class Side> 
void plugIn(Link<T>*& newLink); 


}; 

template<class T> 
template<class Side> 
void Link<T>::plugIn(Link<T>*& newLink)//<<-----why can't I type 
//void Link<T>::plugIn<Side>(Link<T>*& newLink)<---<Side> next to plugIn 


{ 
Side::insert(newLink,this); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
return 0; 
} 

我覺得奇怪的是我必須爲類指定參數,但不能爲函數指定參數。有什麼理由?在類和函數之間的模板中缺乏正交性

回答

1

$14/2 -

模板聲明只能出現一個命名空間範圍或類範圍的聲明。 在函數模板聲明中,聲明符id的最後一個組件應該是模板名稱或運算符函數id(即不是模板id)。 [注意:在類模板聲明中,如果類名是simple-template-id,則聲明聲明類模板部分特化(14.5.5)。末端注]」

標準禁止這樣的語法明確。請參閱本作更多的想法有關template id/template name

+0

所以基本上沒有正交語法保留(通過決定)我是對嗎? – 2010-09-30 11:53:31

+2

@我們無能爲力:是的,我們無能爲力:) – Chubsdad 2010-09-30 11:56:04

+0

是的,我認爲您的文章中的引文在這種情況下是相關的。 'void鏈接 :: plugIn '編譯MSVC++ [only]。刪除我的答案是不正確的。 – 2010-09-30 12:03:50

0

你需要爲了定義它的模板成員函數專門對Link結構。

template<> 
template<class Side> 
void Link<int>::plugIn(Link<int>*& newLink) 
{ 
Side::insert(newLink,this); 
} 

得說實話,這讓我的大腦爆炸一點點。

2

函數模板和類模板是互補的(我稱之爲它們是正交的,但你可以自由地不同意),並且在模板元編程中它們實際上是爲了正交目的。

類模板允許您在模板參數上模式匹配,即。他們提供部分專業

函數模板,相反,不允許部分專門化,但他們允許模板參數推導,這意味着你不必明確寫入模板參數(除了額外的參數,如在你的榜樣)。

我認爲,這解釋了語法的差異,因爲它們在實現方式上有所不同。而且,函數模板可能有重載,類模板不能。

這兩個概念結合起來的方式是

1)有靜態的非模板函數的輔助類模板,如果你想對函數模板偏特:

template <typename T> 
struct doSomethingWithPointersHelper 
{ 
    static void act(T x) { ... } 
}; 

template <typename T> 
struct doSomethingWithPointersHelper<T*> 
{ 
    static void act(T* x) { ... } 
}; 

// This acts as if we had a partial specialization 
// for pointer types 
template <typename T> 
doSomethingWithPointers(T x) 
{ return doSomethingWithPointersHelper<T>::act(x); } 

還有其他的方法來實現這一目標在特定的情況下,但這種方法始終有效。

2)有幫助模板功能,如果你想構建複雜的類時利用參數推導的:在標準庫

template <typename T, typename U> 
struct MyComplexClass 
{ ... }; 

template <typename T, typename U> 
MyComplexClass<T, U> makeComplex(T t, U u) 
{ return MyComplexClass<T, U>(t, u); } 

,你會發現make_pairbind1stmem_fun這使得使用這種技術。