2012-12-23 60 views
3

我有兩個重載的operator(),一個接受任何類型作爲其參數並返回任何類型的函數引用。另一個採用任何類型作爲參數的函數引用,但返回void。在我的類的實例,我得到了以下錯誤:當第一個模板參數Tvoid爲什麼我得到錯誤操作符()不能重載?

In instantiation of 'A<void, int>':
error: 'void A<T, F>::operator()(void (&)(F)) [with T = void, F = int]' cannot be overloaded
error: with 'void A<T, F>::operator()(T (&)(F)) [with T = void, F = int]'

template <typename T, typename F> struct A { 
    void operator()(T (&)(F)) {} 
    void operator()(void (&)(F)) {} 
}; 

void f(int) {} 

int main() { 

    A<void, int> a; 
    a(f); 
} 

這些錯誤只發生。我想知道我在做什麼錯,爲什麼我不能超載operator()這種方式?

+2

您已經定義了一個名爲兩個函數'操作符()'具有相同簽名。你期望什麼? –

+0

@ n.m。當且僅當'T'是'void'時,我想使用第二個'operator()'過載。這基本上是我想要做的,但是Pubby爲我解決了這個問題。 –

+0

出於同樣的原因,爲什麼std :: tuple有一個錯誤的構造函數規範。請參閱http://stackoverflow.com/questions/11386042/confused-by-default-constructor-description-of-stdtuple-in-the-iso-c-standar –

回答

7

那麼,如果Tvoid那麼你有兩個函數定義與完全相同的原型破壞ODR。

嘗試專門的結構來防止這種情況:

template <typename T, typename F> struct A { 
    void operator()(T (&)(F)) {} 
    void operator()(void (&)(F)) {} 
}; 

template <typename F> struct A<void, F> { 
    void operator()(void (&)(F)) {} 
}; 
+0

感謝您的幫助!問題:什麼是ODR? –

+2

@templateboy * [一個定義規則](http://en.wikipedia.org/wiki/One_Definition_Rule) – enobayram