我想在CentOS 7上使用带有clang/clang ++的C++ 11或C++ 14.如何构建这个构建环境?
在嵌入式世界中,人们将硬件(-configuration)-register-mappings编写为结构,这是32位硬件的一个非常简单的例子:
#define hw_baseaddr ((uintptr_t) 0x10000000)
struct regs {
uint32_t reg1;
uint32_t reg2;
};
#define hw_reg ((volatile struct regs *) hw_baseaddr)
void f(void)
{
hw_reg->reg1 = 0xdeadcafe;
hw_reg->reg2 = 0xc0fefe;
}
Run Code Online (Sandbox Code Playgroud)
这非常有效,编译器(gcc至少在我们的平台上)认识到它hw_reg引用了相同的地址(在编译时已知并且是常量)并且ld仅仅是一次.第二个st(存储)使用单个指令完成4字节偏移 - 再次在我们的平台上.
如何使用现代C++(后C++ 11)重现这种行为而不使用#defines?
我们尝试了很多东西:static const课堂内外constexpr.他们都不喜欢(隐含)reinterprest_cast<>.
回应关于为什么改变它的评论:我担心它主要是名利双收.但不仅如此.有了这个C代码调试可能很难.想象一下,你想要记录所有的写访问,这种方法需要你重写所有的地方.但是,在这里,我不是在寻找能够简化特定情况的解决方案,我正在寻找灵感.
编辑只是为了澄清一些评论:我要求这个问题不要改变任何有效的代码(并且写于20世纪90年代).我正在寻找未来项目的解决方案,因为我对define-implementation 并不完全满意,并且问自己现代C++是否具有更高的可能性.
起初我认为它可以用于性能测量.但它说这std::chrono::high_resolution_clock可能是不稳定(is_steady可能false).据说std::chrono::high_resolution_clock甚至可能是别名std::chrono::system_clock通常不稳定.所以我无法用这种类型的时钟来测量时间间隔,因为在任何时刻都可以调整时钟并且我的测量结果是错误的.
同时我无法将时间点转换std::chrono::high_resolution_clock为日历时间,因为它没有to_time_t方法.所以我也无法用这种类型的时钟获得实时.
那可以std::chrono::high_resolution_clock用什么呢?
我遇到了一个我甚至不知道如何描述的编译错误!这完全让我感到困惑.
情况:
代码尝试使用用char*初始化的rvalue std :: string在堆栈上创建一个对象.
代码:
#include <iostream>
#include <string>
class Foo
{
public:
Foo(double d)
: mD(d)
{
}
Foo(const std::string& str)
{
try
{
mD = std::stod(str);
}
catch (...)
{
throw;
}
}
Foo(const Foo& other)
: mD(other.mD)
{
}
virtual ~Foo() {}
protected:
double mD;
};
class Bar
{
public:
Bar(const Foo& a, const Foo& b)
: mA(a)
, mB(b)
{
}
virtual ~Bar() {}
protected:
Foo mA;
Foo mB;
};
int main(int …Run Code Online (Sandbox Code Playgroud) 在C++中,14 void是一个文字类型
类型是文字类型,如果它是:
- 无效; 要么
- 标量类型; 要么
- 参考类型; 要么
- 一个文字类型的数组; 要么
- 具有以下所有属性的类类型(第9条): - 它有一个简单的析构函数,
- 它是聚合类型(8.5.1)或至少有一个constexpr构造函数或构造函数模板,它不是复制或移动构造函数,并且
- 其所有非静态数据成员和基类都是非易失性文字类型.
在C++ 11 void中,不是文字类型
类型是文字类型,如果它是:
- 标量类型; 要么
- 引用文字类型的引用类型; 要么
- 一个文字类型的数组; 要么
- 具有以下所有属性的类类型(第9条): - 它有一个简单的析构函数,
- 非静态数据成员(如果有)的brace-or-equal-initializers中的每个构造函数调用和完全表达式都是一个常量表达式(5.19),
- 它是聚合类型(8.5.1)或至少有一个constexpr构造函数或构造函数模板,它不是复制或移动构造函数,并且
- 它的所有非静态数据成员和基类都是文字类型.
那么为什么是void文字类型呢?它提供了什么好处?
我有一组非正交的策略,它们都实现了一个通用的命名方法,策略添加了安全检查.我希望用户能够组合策略以允许更复杂的验证,而无需手动为每个组合案例创建策略.我的方法是创建一个新的策略类来组合其他人.
下面的简化示例将C显示为组合类,此处将方法ID组合在一起.当在C上调用id时,预期的结果是顺序调用每个基类的id.
#include <iostream>
using namespace std;
struct A
{
void id() { cout << "A ";}
};
struct B
{
void id() { cout << "B ";}
};
template<class A, class... As>
struct C : public A, public As...
{
void id()
{
A::id();
As...::id(); // This line does not work, it is illustrative.
}
};
int main()
{
C<A, B> c;
c.id();
//expected: result A B
}
Run Code Online (Sandbox Code Playgroud)
问题是:是否有可能扩展为...以某种方式这样做而不使用递归方法,只使用...运算符?
我注意到在精美打印元组的上下文中提到了"索引技巧".这听起来很有趣,所以我按照链接.
嗯,那不顺利.我理解了这个问题,但实际上并不能跟踪发生的事情.为什么我们甚至需要任何指数?那里定义的不同功能如何帮助我们?什么是'裸露'?等等
有人可以为参数包和可变元组的专家提供那种东西的游戏吗?
考虑基于范围的for循环的begin-expr和end-expr(N4140 [stmt.ranged]/p1)的规范.鉴于一系列__range类型_RangeT,
begin-expr和end-expr确定如下:
- 如果
_RangeT是一个数组类型,开始-EXPR和最终EXPR是__range和__range + __bound分别,其中__bound在阵列的约束.如果_RangeT是未知大小的数组或不完整类型的数组,则该程序格式不正确;- 如果
_RangeT是一个类型时,不合格-ID小号begin和end被查找类的范围_RangeT由类成员访问查找(3.4.5)那样的话,并且如果任一个(或两者)找到至少一个声明,开始-EXPR和end-expr分别是__range.begin()和__range.end();- 否则,开始-EXPR和最终EXPR是
begin(__range)和end(__range)分别在那里begin和end在相关联的命名空间(3.4.2)的查找.[ 注意:不执行普通的非限定查找(3.4.1).- 结束说明 ]
是否可以在普通的C++代码中模拟这种确切的行为?也就是说,我们可以编写一个magic_begin和一个magic_end功能模板
for(auto&& p : range_init) { /* …Run Code Online (Sandbox Code Playgroud) 我有这个功能模板:
template <class TemplateArgument, template<class> class TemplateType>
TemplateArgument f(const TemplateType<TemplateArgument>& arg)
{
return TemplateArgument();
}
Run Code Online (Sandbox Code Playgroud)
如果这样使用,它无法编译:
struct A {};
template <typename T> struct S {};
template <typename T> struct B : public S<T> {};
struct C : public B<A> {};
int main()
{
f(C());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并且错误消息是:
<source>: In function 'int main()':
<source>:15:10: error: no matching function for call to 'f(C)'
f(C());
^
<source>:2:18: note: candidate: template<class TemplateArgument, template<class> class TemplateType> TemplateArgument f(const TemplateType<TemplateArgument>&)
TemplateArgument f(const TemplateType<TemplateArgument>& arg)
^ …Run Code Online (Sandbox Code Playgroud) C++ 11 std库有几个随机数生成器(RNG),每个生成器实现UniformRandomNumberGenerator概念.然后可以将它们用作随机分布的参数,另请参阅此文档以获取概述.
这种设计的优点是底层RNG引擎的选择与其应用分离.但是,该设计还要求对RNG的所有调用的定义(不仅仅是声明)是可用的(如果RNG类型仍未指定为模板参数).因此,在
struct complicated_random_distribution
{
/*
some data and auxiliary methods here
*/
// complicated; may call RNG::operator() many times
template<typename RNG>
some_type operator()(RNG&gen) const;
};
Run Code Online (Sandbox Code Playgroud)
该成员operator()不能直接在单独的编译单元(CU)中实现,但必须在相同的头文件中(或#include从其中一个d)中可用.
对于单独的实现,理想情况下,想要某种方式来打包RNG的方式与std::function<>打包任何可调用对象的方式相同.(简单地使用std::function和提供单独CU中定义的函数的值RNG::min()和RNG::max()作为参数是限制性的,并且不允许使用,例如,std::uniform_real_distribution<>在内部).
如何才能做到这一点?这个实现是否可用?std库将来会提供这个吗?还是我在吃了一只红鲱鱼?
编辑随机数生成器需要有static成员,min()并且max()使类型擦除变得困难或不可能(GNU的libstdc ++没有做出这种假设,并且使用非静态成员进行类型擦除min()和max()工作,但不能使用LLVM的libc ++,它使用所需的标准static成员).还有办法还能解决这个问题吗?如果没有,这是否意味着C++标准对随机数生成器有一个拙劣的界面?