标签: c++17

正在弃用的std :: iterator的准备工作

3月21 ,标准委员会投票赞成批准P0174std::iterator提议的弃用:

对于读者而言,很长的void参数序列不仅仅是简单地typedef在类定义本身中提供预期的s,这是当前工作草案采用的方法,遵循设置的模式

之前std::iterator,鼓励继承从迭代器样板实现中删除乏味.但弃用将需要以下其中一项:

  1. 迭代器样板现在需要包含所有必需的typedefs
  2. 使用迭代器的算法现在需要使用auto而不是依赖于迭代器来声明类型
  3. 洛基阿斯塔曾建议std::iterator_traits,可以更新,而继承工作std::iterator

有人可以告诉我我应该期待哪些选项,因为我设计了自定义迭代器,着眼于兼容性?

c++ standards iterator deprecated c++17

58
推荐指数
2
解决办法
1万
查看次数

为什么C++ 17中没有std :: construct_at?

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)

c++ placement-new c++17

58
推荐指数
4
解决办法
3055
查看次数

有没有一种很好的方法将std :: minmax(a,b)分配给std :: tie(a,b)?

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)

c++ algorithm stl reference c++17

56
推荐指数
3
解决办法
2311
查看次数

已弃用标头<codecvt>替换

一点前景:我的任务需要将UTF-8 XML文件转换为UTF-16(当然还有正确的标题).所以我搜索了将UTF-8转换为UTF-16的常用方法,并发现应该使用来自的模板<codecvt>.

但现在当它被弃用时,我想知道执行相同任务的新常用方法是什么?

(根本不介意使用Boost,但除此之外我更喜欢尽可能靠近标准库.)

c++ utf-8 utf-16 codecvt c++17

54
推荐指数
4
解决办法
1万
查看次数

std :: memcpy是否在不同的可复制类型之间是未定义的行为?

我一直在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如果将该数组的内容复制回对象,则该对象应随后保持其原始值.[例如:

#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 …
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing undefined-behavior language-lawyer c++17

52
推荐指数
3
解决办法
2898
查看次数

如何在Lambda本身中获取C ++ Lambda函数的地址?

我试图弄清楚如何在自身中获取lambda函数的地址。这是一个示例代码:

[]() {
    std::cout << "Address of this lambda function is => " << ????
}();
Run Code Online (Sandbox Code Playgroud)

我知道我可以在变量中捕获lambda并打印地址,但是我想在执行此匿名函数时就地执行此操作。

有没有更简单的方法?

c++ lambda c++11 c++14 c++17

52
推荐指数
3
解决办法
4314
查看次数

C++中模板参数中auto的优点17

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++ templates auto c++17

51
推荐指数
4
解决办法
2万
查看次数

为什么C++ 17结构化绑定不使用{}?

我在这里找到了*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}",那么会出现一个新的列表语法?为什么?花括号有什么问题?

c++ c++17 structured-bindings

51
推荐指数
4
解决办法
5360
查看次数

reinterpret_cast创建一个简单的默认构造对象

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)

以下是三个问题:

  1. 这个引用是否正确?
  2. 如果是,那么X开始的生命周期是什么时候?如果在线(B),它是否被视为获取存储?如果在线(A),如果有一个分支(A)(B)有条件地构建一个X或其他一些pod,Y怎么办?
  3. 在这方面,C++ 11和C++ 1z之间有什么变化吗?

请注意,这是一个旧链接.针对这个问题,措辞发生了变化.它现在写道:

但是,与C不同,通过简单地重新解释适当对齐的存储来创建具有普通默认构造函数的对象,例如分配的内存std::malloc:placement-new是正式引入新对象并避免潜在的未定义行为所必需的.

c++ language-lawyer c++11 c++17

51
推荐指数
2
解决办法
1812
查看次数

为什么S :: x没有使用?

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)

表达式语句具有表单

expression-statement:
    expression_opt ;
Run Code Online (Sandbox Code Playgroud)

表达式是一个废弃值表达式(第8条)......

但是,这是否足够S::x不被使用?6.2,第3段[basic.def.odr]指出

一种可变x为潜在评估表达式出现的名字exODR使用的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. …

c++ language-lawyer c++17

51
推荐指数
1
解决办法
1681
查看次数