代码之家  ›  专栏  ›  技术社区  ›  Brett Rossier

初始化std::array类型的类继承成员var的最佳方法?

  •  0
  • Brett Rossier  · 技术社区  · 14 年前

    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"}}
            )
        {}
    };
    
    1 回复  |  直到 14 年前
        1
  •  1
  •   Roger Pate Roger Pate    14 年前

    有两个选项,但一个依赖于运行时大小验证。注意,在我的示例中,后者相当于一个cast。铸造有什么问题?

    #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对象,这些数据看起来是相同的。为什么不使用虚拟方法或将共享对象传递给基对象呢?你可以复制那个物体, 下面是与当前代码等效的代码,或者要求它比当前代码长,并存储指针/引用。

    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_;
    }