2010-09-03 86 views
0

實體具有std :: array類型的成員變量。學生從實體繼承,並且需要初始化它繼承的std :: array成員變量。下面是我用來做到這一點的代碼,但它涉及將一個大括號括起來的列表轉換爲std :: array。我不確定這是做到這一點的正確或最佳方式。在沒有轉換的情況下使用大括號括號或雙大括號括起來的列表會導致編譯錯誤。我嘗試了幾種其他的方式來初始化std :: array成員變量沒有成功,所以我似乎被我的當前方法卡住了。有沒有更好的方法來做到這一點?:初始化std :: array類的繼承成員var的最佳方法是什麼?

template<typename... Args> struct Entity { 
    typedef const char* name_t; 
    typedef const array<const char*, sizeof...(Args)> source_names_t; 

    const tuple<Args...> data; 
    name_t name; 

    //This will be initialized by derived class Student. 
    source_names_t source_names; 

    Entity(
     name_t tmp_name 
     , source_names_t tmp_source_names 
    ) 
     : name(tmp_name) 
     , source_names(tmp_source_names) 
    {} 
}; 

//idnum, fname, lname, married 
struct Student : Entity<int, string, string, bool> { 

    Student() 
     : Student::Entity(
      "student" 

      //Now Student initializes the array, but does it by casting. 
      , (source_names_t) {{"id", "lname", "fname", "married"}} 
     ) 
    {} 
}; 
+0

作爲一個風格的筆記,我不認爲'decltype'是一些有名的'typedef'的好替代品。 – 2010-09-03 19:17:26

+0

我看到我可以使用typedef作爲名稱成員,但我是否也可以爲source_names做到這一點?感謝您的建議。總是可以使用更多提示。 – 2010-09-03 19:20:00

+0

'typedef array source_names_type;' – 2010-09-03 19:22:30

回答

1

有兩個選擇,但一個依賴於運行時大小驗證。請注意,在我的例子中後者等同於演員。鑄造有什麼問題?

#include <cassert> 
#include <algorithm> 
#include <array> 
#include <initializer_list> 
#include <iostream> 

struct A { 
    typedef std::array<char const*, 3> T; 
    T data_; 

    A(std::initializer_list<char const*> const& data) { 
    assert(data.size() <= data_.size()); // or == 
    // of course, use different error handling as appropriate 
    std::copy(data.begin(), data.end(), data_.begin()); 
    std::fill(data_.begin() + data.size(), data_.end(), nullptr); 
    } 

    A(T const& data) : data_ (data) {} 
}; 

int main() { 
    A a ({"a", "b"}); 
    std::cout << (void const*)a.data_[2] << '\n'; 

    A b ((A::T{"a", "b"})); // might just be the compiler I tested, but the 
          // extra parens were required; could be related 
          // to "the most vexing parse" problem 
    std::cout << (void const*)b.data_[2] << '\n'; 

    return 0; 
} 

但是,它看起來像這個數據對於每個Student對象是相同的。爲什麼不使用虛擬方法或將共享對象傳遞給基本ctor?您可以複製下面的對象entity_data_(這與您當前的代碼相同),或者要求它存活並存儲指針/引用。

struct Student : Entity<int, string, string, bool> { 
    Student() : Entity<int, string, string, bool>("student", entity_data_) {} 
    // the template arguments are still required in 0x, I believe 
private: 
    static Entity<int, string, string, bool>::source_names_t entity_data_; 
} 
+0

鑄造有什麼問題?呃......我猜想什麼都沒有,我只是不知道我是否錯過了一些重要的東西,或者是否有更好的方法。對我來說,我不得不將一個支撐列表強制轉換爲一個std :: array對象,以便在初始化列表中進行初始化。這樣做與原始數組我認爲會很好,但這是我第一次搞亂W/STD ::數組與原始數組。不太確定要避免什麼。不管怎樣,謝謝。如果在我繪製的場景中沒有人看到該演員陣容存在問題,那麼我猜投射就是要走的路。 – 2010-09-08 12:52:58

相關問題