2010-08-05 235 views
0

我想知道是否以及如何在類成員函數內部定義函數對象以便直接使用它,例如std :: transform函數。
我知道這個例子有點愚蠢,只是爲了展示我遇到的問題。聲明和定義類成員函數內的函數對象

文件 「example.h文件」

class Example { 
    public: 
    //.. constructor and destructor stuff 
    std::string toString() const; //Converts 'mVal' to a std::string 

    private: 
    std::vector<int> mVal; //Only one digit numbers are allowed ([0-9]) 
} 

文件 「example.cpp」

std::string Example::toString() const 
{ 
    //The functor which should be used in std::transform 
    struct { 
    char operator()(const int number) { 
     char c; 
     //"Convert" 'number' to a char 
     return c; 
    }; 
    } functor; 

    //Transform the integers to char 
    std::string str(mVal.size(), '0'); //Allocate enough space 
    std::transform(mVal.begin(), mVal.end(), str.begin(), functor); 
    return str; 

};//toString() 

自從我試圖直接實現一個函數對象的成員函數裏面就像「example.cpp 「,代碼不會被編譯。我得到的錯誤消息是:

error: no matching function for call to ‘transform(__gnu_cxx::__normal_iterator<const int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<const int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Example::toString() const::<anonymous struct>&)’ 

所以我認爲當在std :: transform中使用struct「functor」時出現問題。有人能告訴我問題是什麼嗎?

使用:
在Ubuntu Linux下的gcc-4.2編譯器。

在此先感謝,
勒內。

+0

見http://stackoverflow.com/questions/2662843/c-can-local-class-reference-be-passed-to-a-function – 2010-08-05 08:47:09

+0

可能重複[使用STL算法的本地類](http://stackoverflow.com/questions/742607/using-local-classes-with-stl-algorithms) – 2010-08-05 09:15:43

+0

是的,你是對的。不知道確切的搜索字詞。 – PiJ 2010-08-05 09:31:18

回答

4

正如亞歷山大已經指出的那樣,你不能使用的功能範圍的類型(或沒有名字)作爲模板參數。但是,您可以使用本地類型的靜態成員函數的參數仿函數:

int main() 
{ 
    struct F { 
     static int fn(int x) 
     { 
      return x+x; 
     } 
    }; 

    int v[5]={1,2,3,4,5}; 
    std::transform(v+0,v+5,v+0,F::fn); 
} 

如果您需要在您的函數的局部狀態,不希望訴諸類型擦除成語,那麼你就可以與鑄造本地類型客場欺騙:

int main() 
{ 
    struct F { 
     int k; 
     int call (int n) const 
     { 

      return n+k; 
     } 
     static int fn(void *p, int x) 
     { 
      return ((F*)p)->call(x); 
     } 
    }; 

    int v[5]={1,2,3,4,5}; 
    F f; 
    f.k=123; 
    std::transform(v+0,v+5,v+0,std::bind1st(std::ptr_fun(F::fn),(void*)&f)); 
} 
+0

15行代表lambda表達式......但是,這可以解決問題。 – 2010-08-05 09:48:01

+0

第一個例子是訣竅。感謝那 :) 。 – PiJ 2010-08-05 09:50:53

2

不幸的是,這是行不通的。標準不允許用作模板參數本地類,所以這種方法失敗 (請別人,引用標準的相關部分)

14.3.1/2:「一個地方型,有型沒有鏈接,未命名類型或類型 由任何這些類型複合 不得用作模板 類型參數的 模板參數。

如果您有權訪問C++ 0x編譯器,則可以使用。

局部類本來是強大的,但它們的使用是比較有限的「類型擦除成語」:

struct abstract_foo { ... }; 

template <typename T> 
abstract_foo* make_concrete_foo(...) 
{ 
    struct foo : abstract_foo 
    { 
     // Depends on T 
    }; 

    return new foo(...); 
} 
+0

ISO/IEC 14882 - 14.3.1/2:「一個本地類型,一個沒有鏈接的類型,一個未命名的類型或者由這些類型複合而成的類型不應該被用作一個模板的*模板參數*輸入參數*「。 – 2010-08-05 09:18:16

+0

不幸的是,我現在還不能使用C++ 0x編譯器。但是,無論如何感謝你的答案,很高興知道這是在即將到來的標準。 – PiJ 2010-08-05 09:36:03

+0

@ pij82:看看路德的回答,然後放棄,但這足以滿足你的需求。 – 2010-08-05 09:41:45