3月21 日,标准委员会投票赞成批准P0174中std::iterator提议的弃用:
对于读者而言,很长的void参数序列不仅仅是简单地
typedef在类定义本身中提供预期的s,这是当前工作草案采用的方法,遵循c ++中设置的模式14
在c ++ 17之前std::iterator,鼓励继承从迭代器样板实现中删除乏味.但弃用将需要以下其中一项:
typedefsauto而不是依赖于迭代器来声明类型std::iterator_traits,可以更新,而继承工作std::iterator有人可以告诉我我应该期待哪些选项,因为我设计了自定义迭代器,着眼于c ++ 17兼容性?
C++ 17补充说std::destroy_at,但没有任何std::construct_at对应物.这是为什么?难道不能像下面这样简单地实现吗?
template <typename T, typename... Args>
T* construct_at(void* addr, Args&&... args) {
return new (addr) T(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
这样可以避免不完全自然的放置新语法:
auto ptr = construct_at<int>(buf, 1); // instead of 'auto ptr = new (buf) int(1);'
std::cout << *ptr;
std::destroy_at(ptr);
Run Code Online (Sandbox Code Playgroud) std::tie(a, b) = std::minmax(a, b);
Run Code Online (Sandbox Code Playgroud)
我认为这是直观的代码。干净易懂。太糟糕了,它作为的std::minmax模板无法正常工作const&。因此,如果在内部交换值,则std::pair<const&, const&>一个分配将覆盖另一个值:
auto[a, b] = std::make_pair(7, 5);
std::tie(a, b) = std::minmax(a, b);
std::cout << "a: " << a << ", b: " << b << '\n';
Run Code Online (Sandbox Code Playgroud)
a:5,b:5
此处的预期输出为a: 5, b: 7。
我认为这很重要,因为实现转换功能以将功能应用于某些范围需要直观的lambda声明。例如:
std::vector<int> v{ 0, 1, 0, 2, 0 };
std::vector<int> u{ 1, 0, 1, 0, 1 };
perform(v.begin(), v.end(), u.begin(), [](auto& a, auto& b){
std::tie(a, b) = std::minmax(a, b);
});
//v would be == {0, 0, …Run Code Online (Sandbox Code Playgroud) 一点前景:我的任务需要将UTF-8 XML文件转换为UTF-16(当然还有正确的标题).所以我搜索了将UTF-8转换为UTF-16的常用方法,并发现应该使用来自的模板<codecvt>.
但现在当它被弃用时,我想知道执行相同任务的新常用方法是什么?
(根本不介意使用Boost,但除此之外我更喜欢尽可能靠近标准库.)
我一直在std::memcpy用来规避严格的混叠很长一段时间.
例如,检查a float,像这样:
float f = ...;
uint32_t i;
static_assert(sizeof(f)==sizeof(i));
std::memcpy(&i, &f, sizeof(i));
// use i to extract f's sign, exponent & significand
Run Code Online (Sandbox Code Playgroud)
但是,这次,我检查了标准,我还没有找到任何可以验证这一点的东西.我所发现的是这个:
对于平凡可复制类型T的任何对象(可能重叠的子对象除外),无论对象是否保持类型T的有效值,组成对象的基础字节([intro.memory])都可以复制到char,unsigned char或std :: byte([cstddef.syn])数组.40如果将该数组的内容复制回对象,则该对象应随后保持其原始值.[例如:
Run Code Online (Sandbox Code Playgroud)#define N sizeof(T) char buf[N]; T obj; // obj initialized to its original value std::memcpy(buf, &obj, N); // between these two calls to std?::?memcpy, obj might be modified std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar …
c++ strict-aliasing undefined-behavior language-lawyer c++17
我试图弄清楚如何在自身中获取lambda函数的地址。这是一个示例代码:
[]() {
std::cout << "Address of this lambda function is => " << ????
}();
Run Code Online (Sandbox Code Playgroud)
我知道我可以在变量中捕获lambda并打印地址,但是我想在执行此匿名函数时就地执行此操作。
有没有更简单的方法?
auto在(可能)用C++ 17引入的模板参数中有哪些优点?
它只是auto我想要实例化模板代码的自然扩展吗?
auto v1 = constant<5>; // v1 == 5, decltype(v1) is int
auto v2 = constant<true>; // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>; // v3 == 'a', decltype(v3) is char
Run Code Online (Sandbox Code Playgroud)
我还从这个语言功能中获得了什么?
我在这里找到了*C++结构化绑定的原始提议.它提出了一种轻松绑定多个返回值的方法,即:
auto {a, b} = minmax(data);
Run Code Online (Sandbox Code Playgroud)
但现在我看到每个人都指向C++ 17/C++ 1z提议语法
auto [a, b] = minmax(data);
Run Code Online (Sandbox Code Playgroud)
既然我已经学会了"列表被编写{like,this}",那么会出现一个新的列表语法?为什么?花括号有什么问题?
cppreference †声明:
具有普通默认构造函数的对象可以通过
reinterpret_cast在任何适当对齐的存储上使用来创建,例如在分配有的存储器上std::malloc.
这意味着以下是明确定义的代码:
struct X { int x; };
alignas(X) char buffer[sizeof(X)]; // (A)
reinterpret_cast<X*>(buffer)->x = 42; // (B)
Run Code Online (Sandbox Code Playgroud)
以下是三个问题:
X开始的生命周期是什么时候?如果在线(B),它是否被视为获取存储?如果在线(A),如果有一个分支(A)和(B)有条件地构建一个X或其他一些pod,Y怎么办?†请注意,这是一个旧链接.针对这个问题,措辞发生了变化.它现在写道:
但是,与C不同,通过简单地重新解释适当对齐的存储来创建具有普通默认构造函数的对象,例如分配的内存
std::malloc:placement-new是正式引入新对象并避免潜在的未定义行为所必需的.
从cppreference考虑这个例子:
struct S { static const int x = 1; };
void f() { &S::x; } // discarded-value expression does not odr-use S::x
Run Code Online (Sandbox Code Playgroud)
我同意这&S::x是一个废弃值表达式,因为标准说(9.2,第1段[stmt.expr]来自n4700)
表达式语句具有表单
Run Code Online (Sandbox Code Playgroud)expression-statement: expression_opt ;表达式是一个废弃值表达式(第8条)......
但是,这是否足够S::x不被使用?6.2,第3段[basic.def.odr]指出
一种可变
x为潜在评估表达式出现的名字ex被ODR使用的由ex除非
- ...
- if
x是一个对象,ex是表达式的潜在结果集的一个元素e,其中任何一个
- 左值到左值的转换(7.1)适用于
e或e是丢弃值表达式(第8条).
问题是丢弃值表达式&S::x没有潜在的结果(这意味着它S::x不是潜在的结果&S::x),如6.2,第2段[basic.def.odr]所示:
...表达式的潜在结果集
e定义如下:
- 如果
e是id-expression(8.1.4),则该集仅包含e. …