我有一个关于g ++(版本5.1)下的访问声明的问题.
class Base
{
public:
void doStuff() {}
};
class Derived : private Base
{
public:
// Using older access declaration (without using) shoots a warning
// and results in the same compilation error
using Base::doStuff;
};
template<class C, typename Func>
void exec(C *c, Func func)
{
(c->*func)();
}
int main()
{
Derived d;
// Until here, everything compiles fine
d.doStuff();
// For some reason, I can't access the function pointer
exec(&d,&Derived::doStuff);
}
Run Code Online (Sandbox Code Playgroud)
g ++无法使用以下代码编译上述代码:
test.cpp:实例化'void exec(C*,Func)[用C = Derived; …
我不明白为什么你不能编译一个既有成员(不是默认可构造)又带有大括号或者相同的初始化器和继承的构造函数的类.g ++说:
test.cpp:22:15:错误:使用已删除的函数'Derived :: Derived(float)'
派生d(1.2f);test.cpp:16:13:注意:'Derived :: Derived(float)'被隐式删除,
因为默认定义不正确:
使用Base :: Base;test.cpp:16:13:错误:没有匹配函数调用'NoDefCTor :: NoDefCTor()'
test.cpp:5:1:注意:候选:
NoDefCTor :: NoDefCTor(int)NoDefCTor(int){}
无法编译的代码(在g ++ 5.1下):
struct NoDefCTor
{
NoDefCTor(int) {}
};
struct Base
{
Base(float) {}
};
struct Derived : Base
{
using Base::Base;
NoDefCTor n2{ 4 };
};
int main()
{
Derived d(1.2f);
}
Run Code Online (Sandbox Code Playgroud)
编译的代码,但从不使用 NoDefCTor默认构造函数(尽管显然需要它!):
struct NoDefCTor
{
NoDefCTor(int) {}
NoDefCTor() = default;
};
struct Base
{
Base(float) {}
};
struct Derived : Base
{
using Base::Base;
NoDefCTor …Run Code Online (Sandbox Code Playgroud) 我在armv8(aarch64)中编写了一个简单的内核。
MMU配置:
我正在将新的地址空间(从1 << 40开始)映射到一些空闲的物理区域。当我尝试访问地址1 << 40时,出现异常(类型为“使用SP1的EL1,同步”):
ESR_EL1=0x96000044
FAR_EL1=0xffff010000000000
Run Code Online (Sandbox Code Playgroud)
检查其他寄存器,我有:
TTBR1_EL1=0x82000000
TTBR1_EL1[2]=0x0000000082003003
Run Code Online (Sandbox Code Playgroud)
因此,基于《 ARMv8的ARM体系结构参考手册》(ARMv8-A配置文件):
因此,转换在0级失败,而在0级应该失败。
我的问题是:我做错什么了吗?我是否缺少一些可能导致翻译错误的信息?而且,更一般而言,如何调试翻译错误?
更新:
在启用MMU之前我写表时一切都正常。
每当我在启用MMU之后(通过平面映射表区域)写入表时,映射就永远无法进行。我不知道为什么会这样。
我还尝试了手动写入选定的表(以消除我的mmapping函数的任何副作用):相同的结果(当在MMU开启之前完成写操作时,它会起作用;而在失败之后,它会失败)。
我尝试进行操作tlbi和dsb sy说明,其后isb没有效果。此时只有一个CPU正在运行,因此缓存应该不是问题-编写指令和MMU可以访问相同的缓存(但我将在下一步进行测试)。
我想创建一个以lambda作为参数的函数,并返回一个类型取决于lambda函数返回类型的对象.我想要实现的实际上在实例化时基本上没有明确的模板参数.
现在,这是我的解决方案,我的问题是:是否有更短(更优雅)的方法呢?
template<typename Func, typename RT = std::unordered_map<int,
decltype(((Func*)nullptr)->operator()(T())) > >
RT mapResult(Func func)
{
RT r;
for (auto &i : mData)
r.insert({i.first, func(mData.second)});
return r;
}
Run Code Online (Sandbox Code Playgroud)
为了使它更加清楚一点,λ类型Func需要T&的参数,并返回一个特定类型的载体,和mapResult结果映射的func在unordered_map其_Ty模板参数是lambda函数的返回类型(可能是别的东西,但仍然依赖于这种类型).实际代码要复杂得多,但我正试图明确这一点.
我发现避免RT多次写入类型的唯一解决方案是将它放在模板参数列表中并给它一个默认值,这取决于第一个模板参数(它本身是从函数参数推导出来的).这有点像定义模板化的类型名称.
我正在使用VC12,但希望拥有可在g ++下编译的可移植代码.
然后实例化看起来像这样(虚拟示例):
auto r = c.mapResult([](T &t){return std::vector<int> {(int)t.size()};});
Run Code Online (Sandbox Code Playgroud) 在C++中有2种模板类型(据我所知):模板类和模板函数.为什么不可能有模板模板?(无论是类,功能还是其他模板).是否曾在标准中考虑过?它是否以某种方式破坏了C++语法/精神?我知道这可能听起来很疯狂,并且很容易绕过.
C++有什么可能:
template<bool b>
class TemplateDependingOnBool
{
public:
template<typename T>
class TheTemplateWeWant{};
}
Run Code Online (Sandbox Code Playgroud)
什么会很棒:
template<bool b>
template<typename T>
class TheTemplateWeWant{};
Run Code Online (Sandbox Code Playgroud)
并以基于策略的方式调用它(这是它真正有趣的地方):
template<typename T, template<typename> class ThePolicy = TheTemplateWeWant<true> >
class Foo {};
Run Code Online (Sandbox Code Playgroud)
现在可以做的就是使用:
template<typename T,
template<typename> class ThePolicy = TemplateDependingOnBool<true>::TheTemplateWeWant >
class Foo{};
Run Code Online (Sandbox Code Playgroud)
这不是很优雅.
编辑:
我知道我可以模板化2个参数.目标是将底层模板类(模板化模板)单独使用,无论是模板别名还是模板模板参数(如我的示例所示).基于策略的设计是对Andrei Alexandrescu的Modern C++ Design的参考,这是我要问的功能可能有用的主要原因(因为模板用作模板参数).