2014-06-05 91 views
0

我在C++(還是個初學者)編程,我想知道的一個問題關於自動生成類的價值成員爲字符串,例如:從C++類自動生成屬性成員字符串?

class Point 
{ 
private: 
int x; 
int y; 

public: 
std::list<std::string> getValues(); 
} 

在我看來,我覺得我必須編寫功能的GetValues ,將ints轉換爲字符串並將字符串放入列表中並返回列表,但是我的導師問我是否有辦法自動執行此功能,而不寫入代碼,並且我不知道如何回答。因爲如果我們添加一個新的成員值(例如:int z),我們將不得不重新編碼函數getValues()。顯然有一些方法可以在Java中做到這一點,但我想知道是否有類似的方法到C++。

致以問候

+0

另一種猜測:您的導師希望您將「x」和「y」存儲在動態數據結構中(例如'map '),以便'getValues()'可以在運行時對條目進行迭代。 – Pavel

+0

但是,如果我添加像雙精度的成員屬性。地圖的概念會變得不合時宜? – user3627590

+0

模板怎麼樣? – Pavel

回答

3

很難說你的導師真的想從你那裏得到什麼,但是如果我是你的導師,我希望你瞭解Boost.Fusion Adapted Structures和它基於的技術(特別是typemaps)。

例與Boost.Fusion:

#include <boost/fusion/adapted/struct/define_struct.hpp> 
#include <boost/fusion/algorithm/iteration/fold.hpp> 

#include <boost/lexical_cast.hpp> 

#include <iterator> 
#include <list> 
#include <string> 
#include <iostream> 

BOOST_FUSION_DEFINE_STRUCT(
    (), Point, 
    (int, x) 
    (long, y) 
    (double, z) 
) 

template <class Itr> struct collector_t 
{ 
    using result_type = Itr; 

    template <class T> 
    Itr operator()(Itr itr, T const& val) const { *itr = boost::lexical_cast<std::string>(val); return ++itr; } 
}; 


int main() 
{ 
    Point p {123, 456l, 123.456}; 

    // create and populate the resulting list using boost.fusion facilities 
    std::list<std::string> strings; 
    auto sink = std::back_inserter(strings); 
    boost::fusion::fold(p, sink, collector_t<decltype(sink)>()); 

    // dump the resulting list to prove the example 
    for (auto s: strings) std::cout << s << '\n'; 

    return 0; 
} 
+0

謝謝你的回答,即使對我來說現在聽起來有點困難,我也會去尋找答案。我正在努力工作,沒有像boost(只是標準)的外部圖書館,但我想我將不得不嘗試。 – user3627590

1

在C++中無法自動執行此操作。這需要反思,即代碼必須能夠推理一個類所具有的領域。這在C++中是不可能的。在Java中是可能的,所以你是對的,可以在Java中自動完成。

+0

在C++中沒有什麼是不可能的(請參閱我的回答) – bobah

+0

然後,請給出一些示例代碼如何根據您的鏈接實現他的功能:)。另外,OP談到了爲這個結構添加一個方法。我不確定是否將結構轉換爲boost宏是一個可行的選擇。如果是這樣,你也可以回答OP應該使用'std :: tuple'而不是一個struct,那麼它也是微不足道的。 – gexicide

+0

我搜索關於元組http://en.cppreference.com/w/cpp/utility/tuple,我認爲這可能是一個很好的選擇,我們必須知道的唯一的事情是元組中屬性的正確順序。 – user3627590

0

真正的問題有兩個部分:

  1. 查找所有成員和
  2. 將它們轉換爲字符串。

尋找成員在純C++中是不可能的,因爲它沒有任何形式的反射。您可以使用像Boost.Fusion這樣的標準預處理器來使用特殊的聲明宏,或者您可以使用自己的預處理器,如OpenC++或使用Clang前端。

對於轉換爲字符串,標準的做法將則是這樣的:

template <typename T> 
std::string to_string(T const &v) { 
    std::stringstream s; 
    s << v; 
    return s.str(); 
} 

可避免打字和使用Boost.Lexical Cast

請注意,C++ 11也有std::to_string,但它只是爲數字類型定義的,因此對此目的不是很有用。

1

以非自動化的方式:使用訪問(編譯時)。

是的,這些解決方案需要更多的維護。然而所有的代碼是暴露而不需要在心裏擴大一個宏。因此,潛在的編譯錯誤信息會更加清晰,理解也會得到緩解。

至於維護負擔?

  • 您可以自動化(單元測試)兩種方法(確保它們都返回相同數目的成員以相同的順序)
  • 自動化的殘缺方法檢測稍硬的相關性,但如果成員缺少和測試,它會顯示得

注:我個人比較喜歡as_tuple版本,它使得編寫==<那麼容易。

注意:可以使用sizeof和ABI規則嘗試檢測不完整的方法(缺少成員)。