委员会改变了基于范围的for循环:
C++ 11:
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Run Code Online (Sandbox Code Playgroud)到C++ 17:
{
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Run Code Online (Sandbox Code Playgroud)人们说这将使Ranges TS更容易实现.你能举个例子吗?
考虑这两种可以代表"可选int"的方法:
using std_optional_int = std::optional<int>;
using my_optional_int = std::pair<int, bool>;
Run Code Online (Sandbox Code Playgroud)
鉴于这两个功能......
auto get_std_optional_int() -> std_optional_int
{
return {42};
}
auto get_my_optional() -> my_optional_int
{
return {42, true};
}
Run Code Online (Sandbox Code Playgroud)
... g ++ trunk和clang ++ trunk (with -std=c++17 -Ofast -fno-exceptions -fno-rtti)产生以下程序集:
get_std_optional_int():
mov rax, rdi
mov DWORD PTR [rdi], 42
mov BYTE PTR [rdi+4], 1
ret
get_my_optional():
movabs rax, 4294967338 // == 0x 0000 0001 0000 002a
ret
Run Code Online (Sandbox Code Playgroud)
为什么get_std_optional_int()需要三个mov指令,而get_my_optional()只需要一个 …
我怀疑它可以移植,但有没有解决方案?我认为可以通过创建备用堆栈并在功能输入上重置SP,BP和IP,并使产量保存IP并恢复SP + BP来完成.析构函数和异常安全看起来很棘手但可以解决.
它完成了吗?这不可能吗?
C++ 17添加std::hardware_destructive_interference_size和std::hardware_constructive_interference_size.首先,我认为这只是获取L1缓存行大小的可移植方式,但这是过于简单化.
问题:
static constexpr.如果您构建二进制文件并在具有不同缓存行大小的其他计算机上执行它,这不是问题吗?当您不确定您的代码将运行在哪台机器上时,如何防止错误共享?使用http://en.cppreference.com/w/cpp/string/basic_string_view作为参考,我认为没有办法更优雅地做到这一点:
std::string s = "hello world!";
std::string_view v = s;
v = v.substr(6, 5); // "world"
Run Code Online (Sandbox Code Playgroud)
更糟糕的是,天真的方法是一个陷阱,并留下v暂时的悬挂参考:
std::string s = "hello world!";
std::string_view v(s.substr(6, 5)); // OOPS!
Run Code Online (Sandbox Code Playgroud)
我似乎记得有些东西可能会添加到标准库中以返回子字符串作为视图:
auto v(s.substr_view(6, 5));
Run Code Online (Sandbox Code Playgroud)
我可以想到以下解决方法:
std::string_view(s).substr(6, 5);
std::string_view(s.data()+6, 5);
// or even "worse":
std::string_view(s).remove_prefix(6).remove_suffix(1);
Run Code Online (Sandbox Code Playgroud)
坦率地说,我认为这些都不是很好.现在我能想到的最好的事情是使用别名来简化事情.
using sv = std::string_view;
sv(s).substr(6, 5);
Run Code Online (Sandbox Code Playgroud) 我们假设您需要调用以下方法:
std::tuple<int, int, int> foo();
Run Code Online (Sandbox Code Playgroud)
在C++ 17中,您可以调用该函数并在一行中解压缩元组:
auto [a, b, c] = foo();
Run Code Online (Sandbox Code Playgroud)
现在,我怎么能继续只存储b和c并丢弃a?
目前,我只知道两个选项:
1 - 我可以在自动解包时使用虚拟变量
但是,虚拟变量将被取消并且它将发出警告,因此如果我想要静默警告,那么代码将非常不愉快:
#pragma warning(push)
#pragma warning(disable:4101)
// ReSharper disable once CppDeclaratorNeverUsed
auto [_, b, c] = foo();
#pragma warning(pop)
Run Code Online (Sandbox Code Playgroud)
2 - 我可以存储整个元组并用于std::get检索对我需要的唯一变量的引用.代码不那么令人不愉快,但语法也不那么简单.
此外,对于我们希望保留在元组中的每个新值,此代码的大小增加一行.
auto tuple = foo();
int b = std::get<1>(tuple);
int c = std::get<2>(tuple);
Run Code Online (Sandbox Code Playgroud)
还有另一个更直接的方法来解包元组中的一些参数吗?
我想了解哪些版本的clang Apple安装在我的macbook中,可以看到c ++ 11和/或c ++ 14的功能.我输入了这个命令:
clang --version
//----response
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
Run Code Online (Sandbox Code Playgroud)
但我无法理解什么(clang-700.1.76)意思.如何将此代码转换为clang版本?
这是您可以检查clang版本http://clang.llvm.org/cxx_status.html中提供的c ++功能的站点.
序幕:
std::tuple<int, int, int> f();
std::tuple<int, int, float, int> g();
Run Code Online (Sandbox Code Playgroud)
C++ 1z将引入结构化绑定的语法,这样可以编写代替
int a, b, c;
std::tie(a, b, c) = f();
Run Code Online (Sandbox Code Playgroud)
就像是
auto [a, b, c] = f();
Run Code Online (Sandbox Code Playgroud)
但是,std::tie也允许指定std::ignore忽略某些组件,例如:
std::tie(a, b, std::ignore, c) = g();
Run Code Online (Sandbox Code Playgroud)
是否可以使用新的结构化绑定语法执行类似的操作?它会如何工作?
我有这个测试用例:
struct A{ protected: A(){} };
struct B: A{};
struct C: A{ C(){} };
struct D: A{ D() = default; };
int main(){
(void)B{};
(void)C{};
(void)D{};
}
Run Code Online (Sandbox Code Playgroud)
gcc和clang都用C++ 11和C++ 14模式编译它.两者都在C++ 17模式下失败:
$ clang++ -std=c++17 main.cpp
main.cpp:7:10: error: base class 'A' has protected default constructor
(void)B{};
^
main.cpp:1:22: note: declared protected here
struct A{ protected: A(){} };
^
main.cpp:9:10: error: base class 'A' has protected default constructor
(void)D{};
^
main.cpp:1:22: note: declared protected here
struct A{ protected: A(){} };
^
2 …Run Code Online (Sandbox Code Playgroud) 我查看了一些丑陋的代码(在迭代时修改了基础序列),并探索了基于范围的for循环的定义,我去了cppreference。
在那里,我注意到了一些奇怪的事情:
基于范围的for循环在C ++ 17中已更改,但我看不到更改的原因,并且代码对我来说看起来相同(只是“重构”)。因此,旧的是:
{
auto && __range = range_expression;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Run Code Online (Sandbox Code Playgroud)
新的是
{
auto && __range = range_expression;
auto __begin = begin_expr;
auto __end = end_expr;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Run Code Online (Sandbox Code Playgroud)
为什么要进行此更改,并且它会使任何合法的C ++ 14程序在C ++ 17中表现出未定义的行为(UB)?
c++17 ×10
c++ ×9
c++11 ×2
for-loop ×2
assembly ×1
c++14 ×1
clang ×1
concurrency ×1
constructor ×1
coroutine ×1
llvm-clang ×1
performance ×1
protected ×1
stdstring ×1
tuples ×1
view ×1
x86-64 ×1