1

我打算创建一个变量模板,它采用(变量)模板模板参数和一个类型名:

template <template <typename> auto MetaPredicate, typename T>
constexpr bool has_predicate_v_ = requires {
  { MetaPredicate<T> } -> std::convertible_to<bool>;
}

期望在哪里:

template <typename T>
struct dummy_01 {
    inline static constexpr bool value = true;
};

template <typename T>
inline constexpr bool dummy_01_v = dummy_01<T>::value;

std::cout << std::boolalpha << has_predicate_v_<dummy_01_v, int> << '\n'; // true

但这不起作用。如果它们以标准存在,那将很有用。

另一种情况是创建一个元函数count_if

template <typename Type, template <typename> bool Predicate>
struct count_if {
    inline static constexpr size_t value = /** ... **/;
};

template <typename Type, template <typename> bool Predicate>
inline constexpr size_t count_if_v = count_if<Type, Predicate>::value;

// ...
count_if_v<std::tuple<int, double, void, size_t, unsigned short>, 
           std::is_integral_v> // yields to 3

还有一个与我的问题有关的建议:http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2008r0.html

  • 为什么目前没有可变模板模板参数/参数?
  • 提案的状态如何?
  • 变量模板模板参数/参数是否有任何可能的替代方案?
4

2 回答 2

2

您已经链接到该提案,因此您在很大程度上自己回答了这个问题。您可能不知道可以回答“状态”问题的纸张跟踪器;它说正在寻找更多激励性的例子(这很可能被大流行推迟了),所以也许你应该贡献你的!

至于替代方案,通常的方法是键入特征而不是辅助变量模板。显然,新代码可能必须使用辅助特征类模板包装(基础)变量模板才能利用这一点,但它确实有效。

于 2021-07-06T18:58:26.730 回答
1

扩展@DavisHerring 的答案:我认为它几乎没有用处:我并没有真正看到使用辅助变量模板而不是直接使用特征的优势。例如,我将为您的两个示例做些什么:

C++20中,我实际上会写一个concept

template <template <typename> class Predicate, typename T>
concept is_predicate = requires {
  std::same_as<decltype(Predicate<T>::value), bool>;
};

确保给定谓词具有静态bool成员变量value。在此之前,您可能会另外使用std::enable_if或根本不使用 SFINAE。

示例 1:

template <template <typename> class MetaPredicate, typename T>
requires is_predicate<MetaPredicate, T>
constexpr bool has_predicate_v_ = requires {
  std::same_as<decltype(MetaPredicate<T>::value), bool>;
};

然后用特征has_predicate_v_<dummy_01, int>而不是别名调用它。

在这里试试

示例 2:

template <template <typename> class Predicate, typename... Ts>
requires (is_predicate<Predicate, Ts> && ...)
struct count_if {
  inline static constexpr size_t count = ((Predicate<Ts>::value == true ? 1 : 0) + ...);
};

并再次使用 trait 调用它std::is_integralcount_if<std::is_integral, int, double>::count.

在这里试试

于 2021-07-06T20:11:11.910 回答