2012-10-22 32 views
2

考慮下面的代碼:在模板類:使用一個類方法,如模板參數另一類方法

template < class A > 
class XX { 
    public: 
    template <int (*CC)() > 
    int bla(){ return CC(); } 
    int stam() {return 0;} 
    int f() { 
    return bla<stam>(); 
    } 
}; 

int main() 
{ 
    XX<int> xx; 
    printf(" this is %d\n", xx.f()); 
    return 0; 
} 

test.cpp: In member function ‘int XX<A>::f() [with A = int]’: 
test.cpp:14: instantiated from here 
test.cpp:8: error: ‘int XX<A>::stam() [with A = int]’ cannot appear in a constant-expression** 

失敗想着它很清楚之後。 stam在模板實例化之前不存在,所以它沒有函數地址。當模板被實例化時,實例在代碼中的某個地方被解析,然後stam得到一個地址。因此,地址在編譯時並不是一個常量(儘管可能有一些工作 - 但不支持)。

那麼,爲什麼我試圖做到這一點。我可以使用函數指針或虛函數。在使用stam現實bla(有stam1stam2)稱這是數不勝數倍,即使是輕微的性能改進(如不使用間接)是值得歡迎的。

當然也有解決方案:創建bla1bla2這幾乎是相同的。編寫一個預處理器宏。我想知道是否有一個優雅的解決方案。

+0

即使模板由'XX xx'實例化,'stam'仍然不存在。 –

+0

@ K-BALLO'XX xx'將實例化類用'A = int'並用它,它會實例'XX ::斯塔姆()'和'XX :: F()'。後者參考'XX :: bla <&XX :: stam>'這將實例化方法模板的實例。 –

+0

@Tilman Vogel:不會,'stam'只會在直接或間接使用的情況下被實例化。 –

回答

3

這將編譯OK:

#include <cstdio> 
using namespace std; 

template < class A > 
class XX { 
    public: 
    template <int (XX<A>::*CC)()> 
    int bla(){ return (this->*CC)(); } 
    int stam() {return 0;} 
    int f() { 
    return bla<&XX<A>::stam>(); 
    } 
}; 

int main() 
{. 
    XX<int> xx; 
    printf(" this is %d\n", xx.f()); 
    return 0; 
} 

該修補程序是使用正確的簽名指針到方法的模板參數以及指定方法指針的正確語法。 (實際上,您可以在此處省略<A>。)

+0

謝謝!它編譯。我認爲「this->」不會增加間接性,只會幫助編譯器退出。 – user1766774

+0

@ user1766774那麼,你是通過一個指針調用的,所以我猜,這個調用不能被內聯,但我不確定。 –

相關問題