cuốn sách gpt4 ai đã làm

Cách tạo bản đồ có giá trị là mã định danh mở rộng protobuf trong C++

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-03 07:55:33 26 4
mua khóa gpt4 Nike

Trong protobuf, chúng tôi có một số tùy chọn để triển khai tính kế thừa. "Mở rộng lồng nhau" là một trong số đó: http://www.indelible.org/ink/protobuf-polymorphism/

Điều thú vị ở đây là cách đọc tệp được tuần tự hóa. Chúng ta phải tạo Bản đồ để tương ứng Animal.type với mã định danh mở rộng của nó để chuyển đổi con vật thành Chó hoặc Mèo chính xác. Tuy nhiên, trong ví dụ do trang web trên cung cấp, ngôn ngữ được sử dụng là Python. Điều này có nghĩa là Bản đồ có thể được khởi tạo mà không cần chỉ định loại khóa hoặc loại giá trị. Và nó hoạt động rất tốt:

# Giải nén các byte được tuần tự hóa.
động vật = Động vật()
động vật.ParseFromString(byte)

# Xác định loại tiện ích mở rộng thích hợp để sử dụng.
Extension_map = { Animal.Cat: Cat.animal, Animal.Dog: Dog.animal }
tiện ích mở rộng = động vật.Extensions[extension_map[animal.type]]

Tuy nhiên, để triển khai ánh xạ như vậy trong C++, loại khóa và loại giá trị là bắt buộc. Vì vậy, tôi nên sử dụng loại giá trị nào để lưu trữ hai mã định danh mở rộng khác nhau vào cùng một bản đồ?

Bản đồ ?

Thật không may, điều này rõ ràng không hoạt động.

Tôi cũng sẽ sao chép-dán mô hình viết ở đây: nhập từ động vật_pb2 *

# Xây dựng kiểu thông điệp cơ sở đa hình.
động vật = Động vật()
Animal.type = Animal.Cat

# Tạo loại lớp con bằng cách tham chiếu loại phần mở rộng thích hợp.
# Lưu ý rằng điều này sử dụng trường tự tham chiếu (Cat.animal) từ bên trong
# tiện ích tin nhắn lồng nhau.
cat = động vật.Extensions[Cat.animal]
cat.delawed = Đúng

# Sắp xếp nội dung tin nhắn đầy đủ thành một chuỗi.
# trông đại khái như thế này: [ type [ declawed ] ]
byte = động vật.SerializeToString()

Hàm Extensions() cho phép chúng ta lấy các tiện ích mở rộng của nó bằng cách sử dụng mã định danh của tiện ích mở rộng.

câu trả lời hay nhất

Nếu tôi hiểu chính xác câu hỏi, bạn muốn lưu trữ bản đồ của đối tượng tiện ích mở rộng được xây dựng trong bản đồ để có thể truy cập được sau khi phân tích thông báo.

Trong trường hợp này, có khác nhaubất kìNhập vào tăng cường,thư viện pocoVẫn còn một số. Bạn có thể đặt loại khóa cố định (tức là loại enum hoặc chuỗi) và đặt loại giá trị thành loại biến thể:

#include 
#include
#include
#include
#include

cấu trúc động vật {
std::loại chuỗi;
};

struct Dog : Động vật công cộng {
constexpr tĩnh const char* TYPE = "Con chó";
void vỏ cây() const {
std::cout<<"bow"<<>
}
};

struct Cat : động vật công cộng {
constexpr tĩnh const char* TYPE = "Mèo";
void meow() const {
std::cout<<"meo"<<>
}
};

Nhận nhà máy mở rộng từ tin nhắn:

mẫu 
std::unique_ptr get_extension(Message m) {
thử {
Động vật a( boost::any_cast(m[Animal::TYPE]) );
//để đơn giản
return std::unique_ptr(Động vật mới(a));
} nắm lấy (...) {
trả về std::unique_ptr();
}
}

và cách sử dụng:

int main()
{
// mô phỏng tin nhắn protobuf
std::map m;
m[Dog::TYPE] = Dog();
m[Cat::TYPE] = Cat();

// giao diện chung cho phần mở rộng tin nhắn
chó tự động = get_extension(m);
nếu (con chó)
chó->vỏ cây();
mèo tự động = get_extension(m);
nếu (mèo)
mèo->meo meo();
}

biên dịch@coliru

gia hạn:phiên bản 2Có giao diện phổ quát cho động vật

Một nhiệm vụ thực tế có thể là bạn có một dải thông báo có phần mở rộng và bạn muốn tạo đối tượng một cách linh hoạt. Ở phiên bản thứ hai, bạn cũng có thể "nói chuyện với động vật" thông qua giao diện tương tự:

cấu trúc động vật {
ảo void speak() const = 0;
ảo ~Động vật(){}
};

struct Dog : Động vật công cộng {
constexpr tĩnh const char* TYPE = "Con chó";
ảo void speak() const {
std::cout<<"bow"<<>
}
};
// ... etc

Nhà máy đơn giản để khử tuần tự các loại động vật:

struct AnimalRegistry {
std::map<>()>> người sáng tạo;

mẫu
void register_creator() {
Creators[A::TYPE] = []() { return std::unique_ptr(new A });
}

mẫu
std::unique_ptr create(Message m) {
trả về người sáng tạo[m.animal_type]();
}
};

Cách sử dụng hơi khác một chút:

int main()
{
Cơ quan đăng ký động vật;
register.register_creator();
register.register_creator();

Message đã nhận_message { "Dog" /*đây là một phần của protobuf*/ };

chó tự động = register.create(received_message);
nếu (con chó)
chó->nói();

Nhắn tin another_message { "Cat" };
auto cat = register.create(another_message);
nếu (mèo)
mèo->nói();
}

Về c++ - Cách tạo ánh xạ có giá trị là mã định danh mở rộng protobuf trong C++, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/19975595/

26 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress