The problem seems to lies on c10::Device . If I separate the initialization of c10::device to two part as :
class foo {
  private :
    c10::DeviceType device_type_;
    int16_t index_;

  public:
    foo() : index_(-1), device_type_(c10::DeviceType::CPU){}
    foo(c10::Device device) : index_(device.index()), device_type_(device.type()){}
    foo(c10::DeviceType device_type, int index) : index_(index), device_type_(device_type){}
    int get_index() { return index_; }
    c10::DeviceType get_device_type() { return device_type_; }
};

This would works fine.  So where is the document about this? Why using c10::Device is wrong?