提问人:Post Self 提问时间:11/24/2022 最后编辑:Post Self 更新时间:11/24/2022 访问量:123
为什么 C++ 标准库更喜欢模板而不是枚举?
Why does the C++ standard library prefer templates over enums?
问:
根据 https://en.cppreference.com/w/cpp/algorithm/execution_policy_tag,namespace 定义了各个类型的编译时常量:std::execution
inline constexpr std::execution::sequenced_policy seq { /* unspecified */ };
inline constexpr std::execution::parallel_policy par { /* unspecified */ };
inline constexpr std::execution::parallel_unsequenced_policy par_unseq { /* unspecified */ };
inline constexpr std::execution::unsequenced_policy unseq { /* unspecified */ };
这些值用于参数化其他函数以使用不同的模式。
此目的另一种实现可能如下所示:
enum class policy {
seq,
par,
par_unseq,
unseq,
};
我可能会看到前者比后者有两个好处,但两者都不成立:
- 您可以根据此参数定义函数的单个重载;然而,这在实践中并不是这样做的:有
std::for_each
template<typename ExecutionPolicy, ...>
- 它是可扩展的:用户不能扩展枚举,但用户始终可以定义自己的结构,这通常在整个标准库中是允许的,例如,通过模板专用化;但是,这不适用于此处,因为标准库未指定实现细节;因此,无法创建自己的符合标准的类型
标准库方法的主要缺点是它将使用函数转换为模板,从而使所有内容内联、编译速度变慢等。
当枚举也可以完成这项工作时,对枚举使用单独的类型的原因是什么?标准库中是否有任何预定义枚举的示例?
在编写我自己的库时,我应该模仿这个约定还是在可能的情况下选择枚举?
答:
2赞
user17732522
11/24/2022
#1
无论如何,标准库算法都是模板,因此在这方面没有任何差异。
将枚举方法与所有共享相同类型的策略一起使用的唯一好处是,可以在运行时轻松选择策略。但是,策略的选择必须与所使用的类型/算法相协调。这不太可能有用。
在其他条件相同的情况下,最好对每个策略使用不同的类型,以便在编译时提供更多信息。如果需要,始终可以在实现中丢弃编译时信息,但反之则不可能。
关于您的积分:
仅仅因为标准只指定了一个重载并不意味着实现必须只使用一个重载。允许标准库实现使用任意数量的重载。
无论如何,都不允许专用化或重载标准库函数。
评论
0赞
Post Self
11/24/2022
谢谢,这些观点是有道理的。关于运行时选择的想法很有趣,因此我将为我自己的库选择枚举。注意:您可以在命名空间中专门化模板:en.cppreference.com/w/cpp/language/extending_stdstd
0赞
user17732522
11/24/2022
@PostSelf (通常)允许对类模板进行专业化。专用函数模板则不然。
上一个:模板类型(静态)包装函数?
下一个:删除指针表单模板
评论
template<policy_enum ExecutionPolicy> void f{}
非类型化模板不会推导模板参数值。enum
enum
template<typename... Ts>
std::tuple<Ts...> tpl
[&]<size_t... is>(std::index_sequence<is...>) { return ([&](auto arg) { /* do something with arg, return true to continue */ }(std::get<is>(tpl)) && ...); }(std::make_index_sequence<sizeof...(Ts)>());