- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有以下简单的问题:A类template<typename D> Parser
它定义了一个 ModuleType
作为Module<Parser>
.我想将解析器类型注入(inject)模块,以便能够从其中的解析器中再次提取几种类型。这很方便,因为 Module 中只需要一个模板参数。但是如果解析器需要一些在模块中定义的类型,例如 OptionsType
,问题就来了。 , 在 Parser
中访问它通过使用声明 using ModuleOptions = ...
显然不适用于派生类的实例化 ParserDerived
.错误:error: no type named ‘DType’ in ‘struct ParserDerived<double>’ using DType = typename Parser::DType;
所以不知何故类型
我害怕使用这样的模式,因为我可能会在未来意识到我使用这些模式的所有构造都会崩溃成大量难以理解的编译器故障......
解决以下问题的更好方法是什么?
#include <iostream>
#include <type_traits>
using namespace std;
template<typename Parser>
struct Module{
using DType = typename Parser::DType;
using OptionsType = int;
};
template<typename D, typename Derived = void >
struct Parser{
using DType = D;
using DerivedType = typename std::conditional< std::is_same<Derived,void>::value, Parser, Derived>::type;
using ModuleType = Module<DerivedType>;
//using ModuleOptions = typename ModuleType::OptionsType; //uncomment this!!
};
template<typename D>
struct ParserDerived: Parser<D, ParserDerived<D> >{
using Base = Parser<D, ParserDerived<D> >;
using ModuleType = typename Base::ModuleType;
using DType = typename Base::DType;
};
int main() {
Parser<double> t;
ParserDerived<double> d;
}
最佳答案
这是发生了什么:
d
被定义为 ParserDerived<double>
, 所以它被实例化
Parser<double, ParserDerived<double>>
, 所以它被实例化
DType
被定义为 double
DerivedType
被定义为 ParserDerived<double>
ModuleType
被定义为 Module<ParserDerived<double>>
ModuleOptions
被定义为 Module<ParserDerived<double>>::OptionsType
, 所以 Module<ParserDerived<double>>
被实例化
DType
被定义为 ParserDerived<double>::DType
← 这里有错误OptionsType
被定义为 int
Base
被定义为 Parser<double, ParserDerived<double>>
ModuleType
被定义为 Parser<double, ParserDerived<double>>::ModuleType
DType
被定义为 Parser<double, ParserDerived<double>>::DType
如果你画出这样的实例,很明显 DType
在定义之前使用。模板实例化必须像这样按顺序执行并不是很明显,但 dyp 对你的问题的评论已经回答了它是模板实例化的有效方式,你可以看到这是多个编译器所做的。
您将不得不重新设计。在这种特殊情况下,我认为一种非常可行的方法是(稍微)模仿标准库并提供一个解析器特征类。您将移动 ModuleType
的定义和 DType
那里,以便访问这些定义不需要解析器类的实例化。
回应您的评论:
您是否注释派生类的 DType
应该无关紧要因为不管它是否被定义都看不到,但这是一个很好的问题,为什么基类的 DType
没有被用在它的地方。 Parser<double, ParserDerived<double>>
正在实例化以便将其用作基类,但在该实例化期间它尚未被视为基类。执行实例化后,编译器将首先确保 Parser<double, ParserDerived<double>>
适合作为基类,才可以成为基类。
更短的例子可以更清楚地说明这一点:
template <class B> struct A {
static void f(A &);
static decltype(f(*(B*)0)) g();
};
struct B : A<B> { };
自 B
源自 A<B>
, A<B>::f(A<B> &)
当传递类型为 B
的左值时应该是可调用的.然而,这并不能阻止编译器提示 g
的声明。 ,并且 clang 的错误消息非常明确地调用了 A<B>
和 B
不相关的类型:
error: non-const lvalue reference to type 'A<B>' cannot bind to a value of unrelated type 'B'
这里也会发生这种情况,因为 B
仅因源自 A<B>
而为人所知在 A<B>
的实例化之后已完成。
关于c++ - 如何避免简单的递归模板类型定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24839616/
我正在努力实现以下目标, 假设我有字符串: ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ) ) ) ) ) 我想编写一个正则
给定: 1 2 3 4 5 6
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
大家好,我卡颂。 Svelte问世很久了,一直想写一篇好懂的原理分析文章,拖了这么久终于写了。 本文会围绕一张流程图和两个Demo讲解,正确的食用方式是用电脑打开本文,跟着流程图、Demo一
身份证为15位或者18位,15位的全为数字,18位的前17位为数字,最后一位为数字或者大写字母”X“。 与之匹配的正则表达式: ?
我们先来最简单的,网页的登录窗口; 不过开始之前,大家先下载jquery的插件 本人习惯用了vs2008来做网页了,先添加一个空白页 这是最简单的的做法。。。先在body里面插入 <
1、MySQL自带的压力测试工具 Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、简单、实用的数据库文档(字典)生成工具,该工具支持CHM、Word、Excel、PDF、Html、XML、Markdown等
Go语言语法类似于C语言,因此熟悉C语言及其派生语言( C++、 C#、Objective-C 等)的人都会迅速熟悉这门语言。 C语言的有些语法会让代码可读性降低甚至发生歧义。Go语言在C语言的
我正在使用快速将 mkv 转换为 mp4 ffmpeg 命令 ffmpeg -i test.mkv -vcodec copy -acodec copy new.mp4 但不适用于任何 mkv 文件,当
我想计算我的工作簿中的工作表数量,然后从总数中减去特定的工作表。我错过了什么?这给了我一个对象错误: wsCount = ThisWorkbook.Sheets.Count - ThisWorkboo
我有一个 perl 文件,用于查看文件夹中是否存在 ini。如果是,它会从中读取,如果不是,它会根据我为它制作的模板创建一个。 我在 ini 部分使用 Config::Simple。 我的问题是,如果
尝试让一个 ViewController 通过标准 Cocoa 通知与另一个 ViewController 进行通信。 编写了一个简单的测试用例。在我最初的 VC 中,我将以下内容添加到 viewDi
我正在绘制高程剖面图,显示沿路径的高程增益/损失,类似于下面的: Sample Elevation Profile with hand-placed labels http://img38.image
嗨,所以我需要做的是最终让 regStart 和 regPage 根据点击事件交替可见性,我不太担心编写 JavaScript 函数,但我根本无法让我的 regPage 首先隐藏。这是我的代码。请简单
我有一个非常简单的程序来测量一个函数花费了多少时间。 #include #include #include struct Foo { void addSample(uint64_t s)
我需要为 JavaScript 制作简单的 C# BitConverter。我做了一个简单的BitConverter class BitConverter{ constructor(){} GetBy
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我是 Simple.Data 的新手。但我很难找到如何进行“分组依据”。 我想要的是非常基本的。 表格看起来像: +________+ | cards | +________+ | id |
我现在正在开发一个 JS UDF,它看起来遵循编码。 通常情况下,由于循环计数为 2,Alert Msg 会出现两次。我想要的是即使循环计数为 3,Alert Msg 也只会出现一次。任何想法都
我是一名优秀的程序员,十分优秀!