变体模板别名或函数?

时间:2017-09-10 19:10:32

标签: c++11 variadic-templates

假设需要基于a获得逻辑值 包模板参数,是否有理由更喜欢别名方法 vs功能方法?

示例:

template<bool...> struct bool_pack;
template<bool... bs> 
using all_true = std::is_same<bool_pack<bs..., true>,
                              bool_pack<true, bs...>>;

而不是

template<class none=void>
constexpr bool all_true() { return true; }

template<bool First, bool... Rest>
constexpr bool all_true() {
  return First and all_true<Rest...>();
}

1 个答案:

答案 0 :(得分:1)

编译示例实现所需的时间

当然,

......应该测量。也就是说,我已经看到微基准,std::is_same方法导致编译时间显着缩短;甚至与具有相应编译器的C ++ 17 fold expression (true && ... && bs)相比。作为示例,您提供的递归“函数方法”在编译时性能上应该明显较差。

但是,请注意,通过提供围绕最“高效”(关于编译时工作)实现的包装,可以确保提供最方便的接口。

使用“界面”

的便利性

鉴于这两个选择,我更喜欢别名方法。如果您需要将该帮助程序的结果作为类型(对于继承,具有特化的模板元编程或用于标记分派),则别名会产生比std::bool_constant<all_true_v<some_condition(), some_other_condition()>()>更清晰的语法。另一方面,从别名bool获取all_true<some_condition(), some_other_condition()>{}类型的值很简单(依赖于implicit type conversion)。

从C ++ 14开始,另一个(花哨的?)选择是通过constexpr变量模板提供一个值,该模板具有std::true_typestd::false_type类型。通过隐式转换为bool,可以在需要普通truefalse的情况下使用它,但它也可以作为函数参数传递,而不会失去编译时保证。

template<bool... bs>
constexpr auto all_true_c = typename std::is_same<
    bool_pack<true, bs...>, bool_pack<bs..., true>
>::type{};

遵循现代C ++ {strong>提供两种表单的<type_traits>标题中使用的命名约定可能是一个很好的策略。如果某个实用程序应该提供值,则可以找到辅助变量模板,例如std::is_same_v

template<class T, class U>
inline constexpr bool is_same_v = is_same<T, U>::value;// (since C++17)

如果某个帮助器应该提供类型,则可以找到辅助类型,例如std::decay_t

template<class T>
using decay_t = typename decay<T>::type;// (since C++14)

...除了分别没有后缀的传统工具之外。