将概念传递给功能

And*_*joe 12 c++ templates concept template-meta-programming c++20

由于将概念定义为编译时谓词,是否还可以将这些谓词实际重用于编译时算法?例如,可以检查元组中的所有类型是否都符合概念?据我所知,不可能以任何方式将概念传递给函数,这使我重新回到在这些情况下使用模板。

#include <type_traits>

template<typename T>
concept FloatLike = std::is_same_v<T, float>;

struct IsFloat
{
    template<typename U>
    constexpr static bool test()
    {
       return FloatLike<U>;
    }
};


template<typename Predicate, typename... T>
constexpr bool all_types()
{
    return (Predicate::template test<T>() && ...);
}


int main()
{
   static_assert(all_types<IsFloat, float, float>());
   static_assert(!all_types<IsFloat, float, int>());
}
Run Code Online (Sandbox Code Playgroud)

我想做的就是这样,所以我不必一直包装这个概念就可以使用它:

template<concept Predicate, typename... T>
constexpr bool all_types()
{
    return (Predicate<T> && ...);
}


int main()
{
   static_assert(all_types<FloatLike, float, float>());
   static_assert(!all_types<FloatLike, float, int>());
}
Run Code Online (Sandbox Code Playgroud)

有什么办法可以做到这一点?

Sto*_*ica 5

有什么办法可以做到这一点?

好吧,不,不是真的。不在C ++ 20中。今天的语言中没有模板概念参数的概念。即使变量模板也不能用作模板参数。因此,如果有一个概念开始,我们就不可避免地要包装。

但是我们可以做的是编写更简单的包装器。如果我们同意使用“旧式”类型特征作为谓词,特别是那些行为类似于std::integral_constants的特征,那么我们可以将自己的简洁“概念”定义用作谓词。

template<typename T>
using FloatLike = std::is_same<T, float>;

template<template <typename> class Predicate, typename... T>
constexpr bool all_types()
{
    return (Predicate<T>{} && ...);
}
Run Code Online (Sandbox Code Playgroud)

它的好,因为它可以得到,只要我能看到。