2015-05-29 19 views
0

通過模板類型我有下面的代碼:在f.foo<T>(e);error: expected primary-expression before '>'無法確定,即使它是在

template <typename T> 
struct Data { 
    struct Embed 
    { 
     T t; 
    }; 
}; 

struct Functor { 
    template <typename T> 
    void foo(typename Data<T>::Embed & e) {} 
}; 
template <typename T, typename F> 
struct Caller 
{ 
    F f; 
    template <typename T> 
    void invoke() { 
    typename Data<T>::Embed e; 
    f.foo<T>(e); //compiler error pointed this line 
    } 
}; 

然後我專門的模板:

Caller<int, Functor> c; 
c.invoke(); 

編譯器錯誤。看起來編譯器突然不知道T是什麼,即使它是在函數的模板聲明中指定的。

取出指定在foo.invoke(e)T明確將導致could not deduce template parameter 'T'

我該如何解決這個問題? (我仍然想保持調用者可以具有泛型函子的功能,並且函子的函數可以模板化)。

+0

這可能是因爲您正在爲'calller'調用'invoke()'的相同模板名稱。我不認爲這是允許的。 – NathanOliver

回答

2

您正在使用:

template <typename T> 
void invoke() { 
    typename Data<T>::Embed e; 
    f.foo<T>(e); //compiler error pointed this line 
} 

Caller即使TCaller的參數之一。刪除行

template <typename T> 

,只是使用:

void invoke() { 
    typename Data<T>::Embed e; 
    // f.foo<T>(e); //compiler error pointed this line 
    f.template foo<T>(e); // Need the template keyword here. 
} 

然而,隨着@Nawaz的評論,改變的invoke語義指出。如果T中的invoke與用於實例化CallerT不同,則最好使用不同的名稱,例如U

+2

我認爲它改變了語義。 'invoke'中的'T'可能不同於類模板的'T'。 (f)'需要寫成'f.template foo ()'。 – Nawaz

+0

@Nawaz,真的。更新了答案以反映這一點。 –

+0

@Nawaz我不認爲OP希望'invoke'是一個模板 - 所需的語義是'c.invoke();' – Barry

2

的問題是,fF類型是模板參數,f.foo是一個從屬名稱和這恰好是一個函數模板。所以,你已經在一個非常奇怪的方式使用template

f.template foo<T>(e); 

對於進一步explantion,看到這些:

另外,我建議您使用U作爲功能模板的模板參數invokeif它必須是一個模板,否則你可以使它成爲一個正常的函數(即如果調用的T應該與封閉類模板的T相同)。

希望有所幫助。

相關問題