2009-07-13 105 views
2

考慮下面的類:是否有任何函數對象在STL中創建對象?

class Person { 
public: 
    // I don't want any "char *" to be converted to Person implicitly! 
    explicit Person(const char * name) : name_(name) {}; 

private: 
    std::string name_; 
}; 

還要考慮的char *數據如下數組:

char STUDENT_NAMES[][20] = { 
    "Bart", 
    "Liza", 
    "Maggie" 
}; 

現在,我想根據這個陣列創建的std ::人的名單。 所有我能發明是使用std ::用手寫 函數對象變換算法:

struct CreatePerson : public std::unary_function<const char*,Person> { 
    Person operator() (const char * name) const { 
     return Person(name); 
    }; 
}; 

// ... 

std::list<Person> students; 
std::transform(
    &STUDENT_NAMES[ 0 ], 
    &(STUDENT_NAMES[ sizeof(STUDENT_NAMES)/sizeof(STUDENT_NAMES[0]) ]), 
    front_inserter(students), 
    CreatePerson()); 
// ... 

是否有任何短和/或更明確的方式辦呢?也許一些標準的 函數對象或適配器?

回答

5

您可以通過以下方式使用boost::lambda

#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/construct.hpp> 
#include <string> 
#include <iterator> 
#include <algorithm> 
#include <list> 

struct person { 
    explicit person(char const *name) 
    :name(name) { } 
private: 
    std::string name; 
}; 

int main() { 
    char names[][20] = { 
    "Michael", "litb" 
    }; 

    std::list<person> v; 
    std::transform(names, names + 2, std::front_inserter(v), 
    boost::lambda::constructor<person>()); 
} 

我不認爲這是與標準C++庫的方式。

+0

我希望這陣Calcs(計算)現在是正確的,最後。忽略我的愚蠢提到我在回答什麼時候會產生什麼類型的問題。但是,我仍然建議你讓`STUDENT_NAMES`成爲`char const * names [] = {「Bart」,「Lisa」,...};` - 這樣它不能再溢出20個字符的限制。我不知道你的代碼庫。你是否有充分的理由這樣做? – 2009-07-13 12:01:17

+0

您的解決方案看起來不錯,謝謝! 關於數組大小。感謝您的建議,但這不是問題所在。爲了便於理解,我的示例脫離了上下文並被重寫。 :) – Michael 2009-07-13 12:11:08

+0

@litb:_const_ char names [] [20]不會導致數據重定位,從而允許數據存在只讀存儲器(如EPROM)中。 OTHO,即使_const_ char * names []需要重定位(它是一個指針數組,並且這些指針需要重新定位): http://people.redhat.com/drepper/dsohowto.pdf – 2009-07-13 13:04:48

0

沒有太大的幫助,但不是有一個標準元素宏

sizeof(STUDENT_NAMES)/sizeof(STUDENT_NAMES[0]) 

快速搜索沒有找到它,但我覺得每一個實現我用有它。

我只有其他建議是將CreatePerson轉換爲模板 - 這樣,如果您再次需要它,您只需要做CreateObj或類似的東西。

-1

好吧,我就只能這樣寫的方法/功能:

convert(const char*[] names, std::list<Person>&); 

爲什麼不如果單純做一個簡單的轉換?也許我錯過了這一點?

m2c

2

你的類的構造函數是一個轉換函數。你不需要轉換:你可以插入。看看this code here

std::list<Person> ps(NAMES, NAMES+sizeof(NAMES)/sizeof(NAMES[0])); 

否則,較短的解決方法是使用靜態工廠函數:

struct Person { 
    static Person create(const char* name); 
    .... 
}; 

std::transform(NAMES, NAMES+sizeof(NAMES)/sizeof(NAMES[0], front_inserter(ps), 
    &Person::create); 
相關問題