[英]Dispatch on execution policy by type or enum?
在 C++ 中,我在基於策略的設計模式中基本上有兩種選擇:我可以使用單獨的類型(基於選擇重載)或指定一個包含所有策略的枚舉,我將在運行時分派它們。 現在編寫基於策略的設計的首選方式是什么?
#include <cstdio>
/* Policy using types */
namespace type_policy
{
struct detached_t{};
struct deferred_t{};
inline constexpr detached_t detached = detached_t{};
inline constexpr deferred_t deferred = deferred_t{};
}
auto do_something(type_policy::detached_t pol)
{
printf("detached type policy selected\n");
}
auto do_something(type_policy::deferred_t pol)
{
printf("deferred type policy selected\n");
}
/* Policy using enums */
enum class enum_policy
{
detached,
deferred,
};
static auto do_something_else(const enum_policy pol)
{
if (pol == enum_policy::deferred) {
printf("deferred enum policy selected\n");
} else {
printf("detached enum policy selected\n");
}
}
int main()
{
do_something(type_policy::deferred);
do_something_else(enum_policy::detached);
}
注意:當枚舉分派內置到 static function 中時,編譯器也能夠在編譯時消除條件。 它從一開始也不那么冗長......它應該是首選方式嗎?
我會說這取決於。 您想讓客戶(包括您自己)輕松添加自己的新政策嗎? 如果是這樣,基於類型的設計將允許他們添加新策略而無需重新編譯現有代碼; 他們只需要:
namespace type_policy
{
struct another_t {};
inline constexpr another_t another = another_t{};
}
auto do_something(type_policy::another_t pol)
{
printf("another type policy selected\n");
}
另一方面,基於枚舉的設計只能由枚舉所有者擴展。 此外,如果您更改枚舉以添加新策略,您將迫使客戶重新編譯他們的代碼,即使他們可能對您剛剛添加的新策略不感興趣。
話雖如此,基於類型的設計的一個缺點是策略可能最終分散在許多文件中,而不是基於枚舉的設計,其中所有策略都很好地組合在枚舉 class 中。
基於類型的設計的另一個缺點是它稍微難於使用運行時值(因為你需要知道傳遞給do_something
的確切類型),而不是基於枚舉的,從 int 到enum_policy
的簡單轉換就可以工作正好。
一般來說,枚舉是表達眾多選項之一的自然方式,而不是使用更難理解的類似特征的機制,並迫使您為任何新選項生成新的重載。
關於最后一點,枚舉的使用將通過更小、更清晰的界面簡化對可用策略的更改。 任何基於策略的 function ( do_something_else
) 都會保持一個單一的過載,而不是破壞 API 的兼容性。
最后,自 C++11 以來,與可以從任何 integer 隱式轉換的類 C 枚舉相比,枚舉類的使用提高了它的安全性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.