一个概念可以需要 constexpr 值或函数吗?

jca*_*er2 6 c++ c++-concepts

因此,我想做一些高级的类型级黑客技术,我真的希望能够编写一个概念,要求类型具有constexpr int与其关联的值,稍后我可以在与整数std::array模板参数。

可以写

template<typename T>
concept bool HasCount = requires {
    typename T::count;
};
Run Code Online (Sandbox Code Playgroud)

但这不是我想要的;我想T::count成为一个static constexpr int。但是,代码(甚至不包括所需的constexpr

template<typename T>
concept bool HasCount = requires {
    int T::count;
};
Run Code Online (Sandbox Code Playgroud)

在 GCC 7.3.0 上编译时不会出现“错误:预期的主表达式在 'int' 之前”。

另一个失败的尝试:可以这样写,这需要static int T::count()

template<typename T>
concept bool HasCount = requires {
    {T::count()} -> int;
};
Run Code Online (Sandbox Code Playgroud)

但不是这个,这就是我想要的:

template<typename T>
concept bool HasCount = requires {
    {T::count()} -> constexpr int;
    {T::count() constexpr} -> int; // or this
    {constexpr T::count()} -> int; // or this (please forgive me for fuzzing GCC instead of reading the manual, unlike perl C++ is not an empirical science)
};
Run Code Online (Sandbox Code Playgroud)

因此,我想知道是否有可能以任何方式要求概念表达式具有 constexpr 资格,或者如果没有,是否有原因导致它不可能,或者它是否只是未包含在规范中。

Cas*_*sey 7

理论上,这是可能的,因为要求它是一个有效的表达式,并要求它在需要常量表达式的上下文中T::count使用是有效的。T::count例如:

#include <type_traits>
#include <utility>

template<int> using helper = void;

template<typename T>
concept bool HasCount = requires {
    // T::count must be a valid expression
    T::count;
    // T::count must have type int const
    requires std::is_same_v<int const, decltype(T::count)>;
    // T::count must be usable in a context that requires a constant expression
    typename ::helper<T::count>;
};

struct S1 {
    static constexpr int count = 42;
};
static_assert(HasCount<S1>);

struct S2 {
    int count = 42;
};
static_assert(!HasCount<S2>);

struct S3 {
    static constexpr double count = 3.14;
};
static_assert(!HasCount<S3>);
Run Code Online (Sandbox Code Playgroud)

但实际上,GCC 中概念的实施拒绝了该计划

<source>:20:16: error: invalid use of non-static data member 'S2::count'
 static_assert(!HasCount<S2>);
                ^~~~~~~~~~~~
<source>:18:17: note: declared here
     int count = 42;
                 ^~
<source>:20:16: error: invalid use of non-static data member 'S2::count'
 static_assert(!HasCount<S2>);
                ^~~~~~~~~~~~
<source>:18:17: note: declared here
     int count = 42;
                 ^~
Run Code Online (Sandbox Code Playgroud)

我认为这是一个错误。)