2013-05-21 55 views
4

我有一個模板類,在其中定義引用該模板類的自由函數。這些免費功能也在不同的參數上模板化。如何引用C++中的雙模板自由函數

從課外,我可以撥打免費的功能。但是,我找不到一個免費函數調用另一個的正確語法。

簡單的例子:

template<typename T> class Foo { 
    template<typename S> 
    friend S f(const Foo &) { return S(); } 

    template<typename S> 
    friend S g(const Foo &s) { 
    return f(s); // See below, when instantiated, yields 'no matching function for call to f(const Foo &)' 
    } 
}; 

float test1() { 
    Foo<int> o; 
    return f<float>(o); // Compiles 
} 

float test2() { 
    Foo<int> o; 
    return g<float>(o); // Fails to compile as line above errors 
} 

(C.F. this link太)

似乎被調用點到g內F(S)(),最外面的模板已丟失。我如何在f調用中重新指定T?我檢查了GCC4.7,4.8,clang 3.2都有同樣的錯誤。

回答

6

當您致電f(s)時,您需要指定模板參數S,因爲它無法從參數s推導出來。

但如果你將其更改爲f<S>(s)(假設你的意思是用相同的模板參數Sg被稱爲與調用它),那麼你抑制ADL,並在類範圍內定義友元函數可以發現的唯一途徑是由ADL。因此,您需要向全局名稱空間添加f聲明,以便g中的呼叫可以找到它。

因此使其工作,你需要在gFoo

template<typename T> class Foo; 

template<typename S, typename T> 
    S f(const Foo<T> &); 

template<typename S, typename T> 
    S g(const Foo<T> &); 

添加這些聲明和改變呼叫是f<S>(s)或別的東西,像f<x>(s)

+0

你能證明聲明是什麼樣子?模板化的朋友接受模板化的參數不具有簡單的語法。 –

+0

謝謝 - 這很完美。我的最終解決方案是: template class Foo { }; template S f(const Foo &){return S(); } template S g(const Foo &o){return f (o);} } float test2(){ Foo o; return g (o); } –

+0

@BenVoigt,我已經這麼做了。 –