C++ 概念是否需要constexpr值或函数?
因此,我想做一些高级类型级别的黑客,我真的希望能够编写一个概念,要求一个类型有一个与之相关联的C++ 概念是否需要constexpr值或函数?,c++,c++-concepts,C++,C++ Concepts,因此,我想做一些高级类型级别的黑客,我真的希望能够编写一个概念,要求一个类型有一个与之相关联的constepr int值,稍后我可以在与integerstd::array模板参数相同的概念中使用它 写作是可能的 template<typename T> concept bool HasCount = requires { typename T::count; }; 在GCC 7.3.0上编译时未使用“错误:在'int'之前应使用主表达式” 另一次失败的尝试:可以编写此代码,
constepr int
值,稍后我可以在与integerstd::array
模板参数相同的概念中使用它
写作是可能的
template<typename T>
concept bool HasCount = requires {
typename T::count;
};
在GCC 7.3.0上编译时未使用“错误:在'int'之前应使用主表达式”
另一次失败的尝试:可以编写此代码,这需要静态int T::count()
:
模板
概念bool hascont=需要{
{T::count()}->int;
};
但这不是我想要的:
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)
};
模板
概念bool hascont=需要{
{T::count()}->constexpr int;
{T::count()constexpr}->int;//或此
{CONTXPRPR::COUNTHEOR(})}-int;/或(请原谅我模糊GCC而不是阅读手册,不像Perl C++是一个经验科学)
};
所以,我想知道是否有可能要求一个概念表达式是constexpr限定的,或者是否有不可能的原因,或者它只是没有包含在规范中。理论上,这是可能的,因为要求
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>);
#包括
#包括
使用helper=void的模板;
模板
概念bool hascont=需要{
//T::count必须是有效的表达式
T::计数;
//T::count必须具有int const类型
需要std::is_same_v;
//T::count必须在需要常量表达式的上下文中可用
typename::helper;
};
结构S1{
静态constexpr int count=42;
};
静态断言(hascont);
结构S2{
整数计数=42;
};
静态断言(!hascont);
结构S3{
静态constexpr重复计数=3.14;
};
静态断言(!hascont);
但实际上:
:20:16:错误:非静态数据成员“S2::count”的使用无效
静态断言(!hascont);
^~~~~~~~~~~~
:18:17:注:此处声明
整数计数=42;
^~
:20:16:错误:非静态数据成员“S2::count”的使用无效
静态断言(!hascont);
^~~~~~~~~~~~
:18:17:注:此处声明
整数计数=42;
^~
(这是事实。)不知道是否可以直接用概念编写,但traits是可以做到的,然后在概念中使用它。不是每天你都会为Stackoverflow答案编写十几行代码。编译错误看起来像是因为你。有一件事我真的不明白,那就是为什么需要前面的
:
助手。如果我把helper
(没有:
)作为hascont
的第一行,我不会得到任何编译错误,但是如果我把它作为第二行(在t::count;
之后移动),我会得到错误t::helper不是一个类型
,如果我把它作为最后一行(只需从代码中删除:
)我得到的std::helper尚未声明
。名称空间是否以某种方式从一行传递到下一行?。。。奇怪。另外,谢谢,但我想说的是,自从写了那篇文章之后,我找到了一种不同的、技术稍低的方法来解决我的实际问题:为了方便地定义表示各种数据库查询结果集的类型安全结构。@jcarpenter2我没有忘记S2
中的static
,故意忽略测试概念是否正确地不允许这种类型。是的,名称查找错误取决于需求的顺序。
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)
};
#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>);
<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;
^~