- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在一个新项目中使用 Concepts TS。我的问题与结构模板和我想要创建的关联概念之间的看似循环依赖有关。该概念的具体逻辑是检查该概念的类型参数是否是结构模板的特化。由于我希望该概念可在结构模板内部使用,因此我显然需要在结构模板之前定义该概念,但概念的逻辑也需要了解结构模板。我已经找到了一些可以编译的东西,方法是向前声明结构模板Vector
,然后定义概念VectorSpecialization
,最后定义 结构模板Vector
。我的具体问题与我对结构模板使用 requires
子句有关;当我转发声明它时,编译器会给我一个错误,除非我复制完整的 requires
子句。 (参见下面的代码)。
我的具体问题是:有没有办法避免模板的前向声明和定义之间的 requires
子句完全重复?一种可能性是将 requires 子句的逻辑分解为一个公共(public)实体,声明和定义都可以委托(delegate)给该实体,我认为这将解决 DRY 原则;但我很好奇我是否可以在这里做出更高级别的结构决策,以避免在两个地方都需要 requires
子句,或者是否有更惯用的方法来使用概念我可以从中受益的类似用例。重申一下,我所说的用例是:编写一个将在模板中使用的概念,但该概念还需要了解模板。
// Forward declare the struct template so that the concept can refer to it
// Note the need to repeat the 'requires' clause. Can that repetition be
// be avoided?
template< typename T, size_t N > requires N > 1 struct Vector;
// compile-time overload set using template arg deduction to detect
// when the argument is a specialization of 'Vector'
template< typename NonVector >
constexpr bool IsVectorSpecialization( NonVector && ) {
return false;
}
template< typename T, size_t N >
constexpr bool IsVectorSpecialization( Vector<T, N> && ) {
return true;
}
// The concept, which uses the above overloaded constexpr function
template< typename VectorCandidate >
concept bool VectorSpecialization_CV
= IsVectorSpecialization( std::declval<VectorCandidate>() );
template< typename T, size_t N >
requires N > 1
struct Vector : std::array<T, N> {
// Some function templates with VectorSpecialization parameters, e.g.
// T dot( VectorSpecialization const &other ) const;
// ...
};
(注意:除了具体问题之外,我还欢迎讨论(当然是在评论中)有关与此问题和/或人们提供的解决方案有关的概念 TS 设计的各个方面,因为我使用 Concepts TS 的部分原因是想看看它在实践中的表现如何,看看在完全标准化之前委员会是否有任何有用的反馈。例如,“Concepts Lite”的设计是否有调整“这可以消除像这样重复 requires
子句的需要吗?)
最佳答案
受约束模板提供的保证之一是,每当命名模板专门化时,参数都必须满足约束。请参阅 P121R0 §14.3 [temp.names]/8:
When the template-name of a simple-template-id names a constrained non-function template or a constrained template template-parameter, but not a member template that is a member of an unknown specialization (14.7), and all template-arguments in the simple-template-id are non-dependent 14.6.2.4, the associated constraints of the constrained template shall be satisfied. (14.10.2).
在您的示例中,这意味着例如命名 Vector<int, 1>
格式不正确即使没有实例化它:
template< typename T, size_t N > requires N > 1 struct Vector;
using foo = Vector<int, 1>*;
// ill-formed: constraints not satisfied: '(N > 1)' evaluated to false
如果可以在没有关联约束的情况下声明模板,则无法强制执行该保证。关联的约束是声明的关键部分。
这在函数模板的上下文中更加明显,否则具有不同关联约束的相同函数模板声明声明重载。例如:
template<typename T>
requires true
bool foo(T) { return true; }
template<typename>
constexpr bool always_false = false;
template<typename T>
requires always_false<T>
bool foo(T) { return false; }
这是一个完全有效的程序,它声明了两个名为 foo
的重载函数模板。 ,其中第二个永远不会被重载决策选择。同样,相关的约束是声明的一个显着特征。有必要在每个声明中重复关联的约束,就像重复模板实体的名称或参数的数量和种类一样。
概念是语言提供的管理这种重复的机制:我们为它们提供方便的名称,而不是一遍又一遍地重复巨大的约束表达式。 N > 1
还不足以需要一个命名概念来节省击键次数,但是 providing a single point of definition for the notion is clearly worthwhile :
template< size_t N > concept bool VectorLength = N > 1;
template< typename T, VectorLength N > struct Vector;
template< typename >
constexpr bool IsVectorSpecialization = false;
template< typename T, size_t >
constexpr bool IsVectorSpecialization<Vector<T, N>> = true;
template< typename VC >
concept bool VectorSpecialization = IsVectorSpecialization<VC>;
template< typename T, VectorLength N >
struct Vector : std::array<T, N> {
T dot( VectorSpecialization const& );
};
确实没有其他选择来定义这种结构。概念无法前向声明的事实有时很烦人,但我发现已分解为避免无法表达的循环依赖所需的线性结构的设计非常容易理解。
关于c++ - 避免在模板的前向声明中出现重复的 require 子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40925053/
前一段时间写过一篇文章《 实战,一个高扩展、可视化低代码前端,详实、完整 》,得到了很多朋友的关注。 其中的逻辑编排部分过于简略,不少朋友希望能写一些关于逻辑编排的内容,本文就详细讲述一下逻辑
我正在尝试以下 Java 片段: int[] testArray={10,20,30,40}; int i= 0; testArray[i++]= testArray[i++]+1; System.o
我想知道我是否可以通过某种方式在 C++ 中进行前/后函数调用。我有一个包含很多函数的包装器类,在每次调用包装器函数后,我应该调用另一个始终相同的函数。 所以我不想像这样对每个函数调用 postFun
我有一个像这样的头文件: #pragma once #include "gamestate.h" #include "ExitListener.h" class InitialGameState :
学习左值和右值。定义是任何可以是“地址”的东西都是左值,否则就是右值。 我检查了运算符的优先级,前缀和后缀增量都比“地址”运算符具有更高的优先级。 对于下面的两个例子,谁能解释一下为什么第一个“&++
在我的学习过程中,我遇到了前后迭代器,我想知道是否有办法让它们就地创建容器元素。从文档来看,容器似乎需要实现 push_back 函数才能与 back_iterator 一起使用。但是有没有一种方法可
我有两个关于 Java 中运算符优先级的类似问题。 第一个: int X = 10; System.out.println(X++ * ++X * X++); //it prints 1440 根据
请放轻松,不要对我开枪,因为我还是新手。 当我运行这段代码时,我完全糊涂了,终生无法弄清楚为什么: int y = 9; cout << "++y = " << ++y << "\n--y = " <
两种表达方式有区别吗: (*x)++ 和 ++(*x) 我可以看到这两个语句都替换了 *x 中 (*x+1) 的内容。但是它们之间有什么区别吗? 最佳答案 (*x)++ 计算为*x的值;作为副作用,*
我有一个如下所示的数据集: Date CONSUMER DISCR CONSUMER STAPLES ENERGY FINANCIALS HEALTH CARE
我希望检查名称字段中输入的前两个字符是否为字母 - 除此之外没有什么区别(空格、'、- 等都是公平的游戏)。这是我到目前为止所拥有的,但它不起作用。想法?谢谢! if (document.form01
我制作了一个简单的脚本,为像素和所有附近的像素着色为相同的颜色 Click foto
我需要编写一个循环,以下列格式输出从昨天算起的最近 30 天: 2014-02-02 2014-02-03 2014-02-04 ... 2014-03-04 我想我需要像这样使用循环: for ($
我正在做一些练习,但我对这个感到困惑: public static int f (int x, int y) { int b=y--; while (b>0) { if (x%2!=0
我需要一个 4 个字符的正则表达式。前 3 个字符必须是数字,最后 1 个字符必须是字母或数字。 我形成了这个,但它不起作用 ^([0-9]{3}+(([a-zA-Z]*)|([0-9]*)))?$
我需要编写一个循环,以下列格式输出从昨天算起的最近 30 天: 2014-02-02 2014-02-03 2014-02-04 ... 2014-03-04 我想我需要像这样使用循环: for ($
我有下面的程序,我试图找到前 1000 个素数的总和。在代码中,解决方案1和2有什么区别?为什么我不应该将 count 变量放在 if 条件之外?如果我把变量放在 if 之外,我显然没有得到我需要的答
这个问题在这里已经有了答案: Replace First N Occurrences in the String (7 个答案) 关闭 4 年前。 我有一个如下的字符串 const str = '_
我正在尝试测量以纳秒为单位的平均访问延迟,但在第一次迭代后我收到“段错误(核心转储)”。我错过了什么吗?我是否滥用了指针。这是导致错误的函数: #include #include #include
我有一个 SQL 问题 (MySQL)。我如何从下表创建一个新表(表名称:“well_master_prod_inj”)。 我需要按井名和日期聚合数据。我希望每个井名只有一行数据以及显示以下数据的列:
我是一名优秀的程序员,十分优秀!