Có cách nào để truyền std :: any chứa con trỏ dẫn xuất sang con trỏ cơ sở mà không biết loại dẫn xuất không?


8

Giả sử tôi có một std::anyđối tượng có thể có hoặc không chứa con trỏ tới một lớp dẫn xuất của một lớp cơ sở nhất định B. Có cách nào tôi có thể làm một cái gì đó:

  1. Trả về a B *, nếu std::anyđối tượng giữ một cái gì đó có thể chuyển đổi thành B *, hoặc
  2. Ném một ngoại lệ nếu không?

Có vẻ như dynamic_caststd::any_castmỗi cái cung cấp một nửa chức năng này, nhưng tôi không thấy bất kỳ cách nào để kết hợp cả hai.

Tôi biết rằng tôi có thể thực hiện công việc này theo nhiều cách khác nhau liên quan đến việc liệt kê rõ ràng mọi loại chuyển đổi thành B *, nhưng đó là mẹ của tất cả các vi phạm DRY.


Trường hợp sử dụng mẫu:

std::vector<std::any> setupTools(const std::string & confFile)
{
  std::vector<std::any> myTools;

  auto conf = parse(confFile);

  for(std::string & wrenchInfo : conf["Wrenches"])
  {
    Wrench::setup(myTools, wrenchInfo);
  }    

  for(std::string & hammerInfo : conf["Hammers"])
  {
    Hammer::setup(myTools, hammerInfo);
  }

   // 25 more kinds of tools
}

Factory1::init(const std::vector<std::any> & tools)
{
  m_wrench = any_get<Wrench *>(tools);
  m_hammer = any_get<Hammer *>(tools);
  m_saw = any_get<Saw *>(tools);
}

Factory2::init(const std::vector<std::any> & tools)
{
  m_wrench = any_get<TorqueWrench *>(tools);
}

Factory3::init(const std::vector<std::any> & tools)
{
  m_saw = any_get<CordlessReciprocatingSaw *>(tools);
}

Tôi không muốn bao gồm một loạt mã soạn sẵn liệt kê từng loại cưa duy nhất để tôi có thể lấy một cái cưa - bất kỳ Saw - để sử dụng Factory1.


1
Bạn có thể đưa ra một số lời giải thích về lý do tại sao bạn cần sử dụng std::anycho việc này, và những gì bạn đang cố gắng giải quyết tổng thể? Điều này có vẻ như là một vấn đề rất khó xử và có lẽ có một cách tốt hơn xung quanh nó
thay đổi igel

3
Có nguy cơ nêu rõ ràng, nếu bạn đồng ý chỉ đưa B*s vào std::anyđối tượng và không dẫn xuất con trỏ lớp, thì điều đó sẽ giải quyết vấn đề khá dễ dàng.
Brian

2
Nếu nó không phù hợp với trường hợp sử dụng của bạn thì bạn có thể giải thích trường hợp sử dụng của bạn không?
Alan Birtles

1
Nếu tất cả myToolsđều là công cụ tại sao không chỉ có một Toollớp cơ sở và tạo myToolsmột std::vector<std::unique_ptr<Tool>>?
Alan Birtles

1
@DanielMcLaury: " không có chức năng chồng chéo giữa cưa và búa " Vậy tại sao chúng lại nằm trong cùng một mảng? Rõ ràng có một số điểm chung logic giữa chúng, bởi vì bạn dường như muốn gắn chúng ở cùng một nơi. Đó là, tôi không hiểu tại sao myToolstồn tại; Tại sao bạn muốn đặt những gì bạn tuyên bố là những đối tượng hoàn toàn khác nhau vào nó, sau đó lặp đi lặp lại chúng để cố nhớ những gì bạn đặt ở đó?
Nicol Bolas

Câu trả lời:


2

Điều này là không thể tin được. Chỉ có thể lấy một đối tượng ra khỏi std::anyviệc sử dụng chính xác loại được đặt bên trong. Vì vậy, bạn phải biết loại để có được bất cứ điều gì từ nó.

Có vẻ như std::anykhông phù hợp với trường hợp sử dụng của bạn.


0

Thêm một "Công cụ" lớp cơ sở có thuộc tính ToolType enum có thể giúp đỡ. Sau đó, sử dụng ToolType, bạn có thể quyết định chọn diễn viên.


1
Điều này có thể làm việc, tôi đã thấy nó được thực hiện. Nhưng đó là một mùi mã lớn, tôi sẽ không đề nghị nó.
Đánh dấu tiền chuộc

Vâng, tôi đồng ý với bạn, sẽ tốt hơn để suy nghĩ lại về kiến ​​trúc.
Pedro Ferreira
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.