2012-10-13 51 views
1

我該如何聲明我想要一個const函數引用(在模板 參數中)?例如,const引用模板參數中的函數?

template< bool (&func)(int arg) > 
void foo(int stuff); 

但是const?

更具體地說,如果我嘗試編譯icpc如下:

template<bool (&func)(int arg)> 
bool id(int arg) { 
    return func(arg); 
} 

class Foo { 
public: 
    Foo() {}; 
    virtual ~Foo() {}; 
    bool bar(int arg) { return true; } 
    bool bar2(int arg) { 
    return id<bar>(arg); 
    }; 
}; 

int main() { 
    return 0; 
} 

我得到

$ icpc foo.cpp 
foo.cpp(12): error: no instance of function template "id" matches the argument list 
      argument types are: (int) 
     return id<bar>(arg); 
      ^
compilation aborted for foo.cpp (code 2) 

,或者用g++,我得到

$ g++ foo.cpp 
foo.cpp: In member function ‘bool Foo::bar2(int)’: 
foo.cpp:13:23: error: no matching function for call to ‘id(int&)’ 
    return id<bar>(arg); 
        ^
foo.cpp:13:23: note: candidate is: 
foo.cpp:2:6: note: template<bool (& func)(int)> bool id(int) 
bool id(int arg) { 
    ^
foo.cpp:2:6: note: template argument deduction/substitution failed: 
foo.cpp:13:23: error: could not convert template argument ‘Foo::bar’ to ‘bool (&)(int)’ 
    return id<bar>(arg); 
        ^

但如果不是我將欄移到頂層,如

template<bool (&func)(int arg)> 
bool id(int arg) { 
    return func(arg); 
} 

bool bar(int arg) { return true; } 

class Foo { 
public: 
    Foo() {}; 
    virtual ~Foo() {}; 
    bool bar2(int arg) { 
    return id<bar>(arg); 
    }; 
}; 

int main() { 
    return 0; 
} 

它編譯得很好。爲什麼會發生這種情況,我怎樣才能解決這個問題,而不會讓酒吧成爲全球?

注:在我的原代碼,我得到的錯誤 「(不是常量限定)不能與類型的值進行初始化」: (與icpc

CollisionWorld.cpp(73): error: a reference of type "bool (&)(const Line &, vec_dimension={double}, vec_dimension={double}, vec_dimension={double}, vec_dimension={double})" (not const-qualified) cannot be initialized with a value of type "bool (const Line &, vec_dimension={double}, vec_dimension={double}, vec_dimension={double}, vec_dimension={double})" 
    QuadTree<Line, vec_dimension, line_inside_box_with_time> *quad_tree = 
           ^

(與g++

CollisionWorld.cpp:73:58: error: could not convert template argument ‘CollisionWorld::line_inside_box_with_time’ to ‘bool (&)(const Line&, double, double, double, double)’ 
    QuadTree<Line, vec_dimension, line_inside_box_with_time> *quad_tree = 
                 ^
+0

這與constness無關。會員功能不是功能! –

+0

@KerrekSB成員函數是函數。如果您在不調用成員函數的情況下命名該成員函數,則它是函數類型的右值表達式。可能他們試圖給出一個很好的診斷,並檢查初始值是否是右值,但忘記了成員函數初始值設定項。 –

+0

@ JohannesSchaub-litb:你可以調用一個函數,但是你不能調用成員函數。你需要一個*對象*。這是很多人在嘗試進行小回調時會感到困惑的,所以我想嘗試一下這個激進聲明,希望它能讓人們去思考一個成員函數究竟是什麼...... –

回答

1

問題是,該模板需要一個免費的功能,而不是一個成員funciton。這就是爲什麼當你把條(它的工作原理)出來的Foo,

試試這樣說:

​​
+0

http: //stackoverflow.com/questions/4387971/c-passing-method-pointer-as-template-argument是相關的。 – perh

0

要調用一個成員函數,你需要兩樣東西:this指針和功能。因此,它不可能像你寫的那樣簡單。 id將需要this指針!

模板定義是這樣的:

template<bool (Foo::*func)(int)> 

但儘管如此,你無法實現真正​​的id功能上的功能和成員函數是雙向。