簡體   English   中英

Function參數如何使用Nested-Function-Type? C++

[英]How To Use Nested-Function-Type As The Function Parameter? C++

問題

void function(InnerType const& inputs) {
  struct InnerType {
    // All the function required parameters
  };
}

是否可以修復有關 function 參數類型的編譯器錯誤?

可能的解決方案

struct InnerType;
void function(InnerType const& inputs) {
  struct InnerType {
  };
}

但是當我們嘗試使用它時,它會因“不完整類型”錯誤而失敗。

用法

在我最近的項目中,我必須處理很多 C API,包括第三方庫和 Kernel API。

  • 首先我嘗試包裝這些函數,但很快我想出了很多重復的代碼來處理瑣碎的事情(比如檢查 API 先決條件,其中一些在不同的名稱/上下文下具有相同的代碼),
  • 然后我嘗試使用模板編程將條件的邏輯隱藏在模板下。
  • 沒過多久,我就為一個任務(刪除重復)想出了很多不可讀的模板代碼。

所以我認為,如果我們可以有一個嵌套函數類型,我們可以輕松地將 API 參數包裝在 C++ function 中,以避免使用重復代碼的全新class

我的限制

  • 我無法在 function 的同一命名空間中定義該struct 。因為所有 API 處理程序都在同一文件中定義,並且很難選擇唯一的名稱。
  • 我無法為每個處理程序創建一個文件,因為我們已經有很多文件了。

我的優先事項

  • 可讀性
  • 可維護性
  • 強類型(用於處理 C API)

例子

Expected<ReturnType> GetDataFrom(FunctionParamType const& inputs) {
  struct FunctionParamType {
    String string;
    Integer index;
  };
  ThrowExceptionOnEmptyString(inputs.string, "Missed Something");
  ThrowExceptionOnZeroInteger(inputs.index, "Wrong Index");

  // Call The API
}

// Usage
auto const result = GetDataFrom({.string = "something", .index = 1});

代替:

class DataApi {
public:
  void setString(String const& string) {
    ThrowExceptionOnEmptyString(string, "Missed Something");
    string_ = string;
  }
  void setInteger(Integer const& interger) {
    ThrowExceptionOnZeroInteger(integer, "Wrong Index");
    integer_ = integer;
  }
  String getString() const noexcept { return string_; }
  Integer getInteger() const noexcept { return integer_; }

  DataApi(String const& string, Integer const& integer)
    : string_(string), integer_(integer) {
    ThrowExceptionOnEmptyString(string, "Missed Something");
    ThrowExceptionOnZeroInteger(integer, "Wrong Index");
  }
  DataApi() = default;

  Expected<ReturnType> execute() {
    // Call The API
  }
  
private:
  String string_;
  Integer integer_;
};

// Usage
auto const result = DataApi("Something", 1).execute();

這種方法怎么樣:

namespace some_api_function {
    struct parameter_type {
        ...
    };
    struct return_type {
        ...
    };
    return_type call(parameter_type p) {
        ...
    }
}

唯一更改的名稱是周圍命名空間的名稱。 parameter_typecallreturn_type在各種 API 包裝器中保持不變。

順便說一句:您為參數結構驗證設置器的方法是有缺陷的。 特別是,如果您不從構造函數開始就建立該保證,則不能保證參數正確。 此外,如果兩個參數的正確性相互依賴,則該方法不適用於單獨的設置器。

相反,考慮再編寫兩個函數validate() ,您首先調用參數,最后調用結果。 這也是在代碼中清楚記錄這些要求的好方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM