Questions tagged «c++17»

C ++ 17是2017年批准的C ++标准的名称。它以以前的C ++ 14标准为基础,改进了核心语言和标准库,并添加了一些新的语言功能。

4
不允许隐式转换返回
#include <optional> bool f() { std::optional<int> opt; return opt; } 无法编译: 'return': cannot convert from 'std::optional<int>' to 'bool' 咨询参考本来可以找到解释的,但我读了应该可以。 每当在上下文中使用某种类型T1的表达式但不接受该类型但接受某种其他类型的T2时,都会执行隐式转换。特别是: 当调用以T2作为参数声明的函数时,将表达式用作参数时; 当表达式用作期望T2的运算符的操作数时; 初始化类型为T2的新对象时,包括返回T2的函数中的return语句; 当在switch语句中使用该表达式时(T2是整数类型); 在if语句或循环中使用该表达式时(T2为bool)。

3
通过给定条件拆分给定的std :: variant类型
如何通过给定的变体类型 using V = std::variant<bool, char, std::string, int, float, double, std::vector<int>>; 声明两个变体类型 using V1 = std::variant<bool, char, int, float, double>; using V2 = std::variant<std::string, std::vector<int>>; 其中V1包括来自的所有算术类型,V并V2包括来自的所有非算术类型V? V 可以是模板类的参数,例如: template <class V> struct TheAnswer { using V1 = ?; using V2 = ?; }; 通常,条件可以是这样的constexpr变量: template <class T> constexpr bool filter;
20 c++  c++17  std-variant 


4
将std :: transform与std :: back_inserter一起使用是否有效?
Cppreference具有以下示例代码std::transform: std::vector<std::size_t> ordinals; std::transform(s.begin(), s.end(), std::back_inserter(ordinals), [](unsigned char c) -> std::size_t { return c; }); 但这也说: std::transform不保证unary_op或的顺序应用binary_op。要将功能按顺序应用于序列或将功能修改序列的元素,请使用std::for_each。 大概是为了允许并行实现。但是,第三个参数std::transform是a LegacyOutputIterator,它具有以下条件++r: 此操作之后,r不需要是可递增的,并且r不再需要先前值的任何副本是可取消引用或可递增的。 因此在我看来,输出的分配必须按顺序进行。它们是否仅表示的应用程序unary_op可能会乱序,并存储到一个临时位置,但按顺序复制到输出中?这听起来不像您想做的事情。 大多数C ++库实际上尚未实现并行执行程序,但Microsoft已实现。我很确定这是相关的代码,并且我认为它调用此populate()函数来将迭代器记录到输出的大块中,这肯定不是一件有效的事情,因为 LegacyOutputIterator可以通过递增其副本来使其无效。 我想念什么?

1
为什么std :: atomic构造函数在C ++ 14和C ++ 17中表现不同
我在使用C ++ 11的项目中工作,并且尝试了以下代码 #include <atomic> struct A { std::atomic_int idx = 1; }; int main() { return 0; } 我收到编译器错误 error: use of deleted function 'std::__atomic_base<_IntTp>::__atomic_base(const std::__atomic_base<_IntTp>&) [with _ITp = int]' std::atomic_int idx = 1; ^ 对于C ++ 14,结果相同。当我切换到C ++ 17时,它可以工作:wandbox 我检查了cppreference的区别: std::atomic std::atomic<T>::operator= std::atomic<T>::atomic 但是C ++ 14和C ++ 17之间没有任何区别。为什么它与C …
19 c++  c++14  c++17  stdatomic 

4
连续枚举C ++ 11
有没有一种方法可以在C ++ 11中检查枚举是否连续? 给出一个不是的枚举值是完全有效的。在C ++ 14,C ++ 17或C ++ 20中是否可能有类似类型特征的功能来检查枚举是否连续?这将在static_assert中使用。 一个小例子如下: enum class Types_Discontinuous { A = 10, B = 1, C = 100 }; enum class Types_Continuous { A = 0, B = 1, C = 2 }; static_assert(SOME_TEST<Types_Discontinuous>::value, "Enum should be continuous"); // Fails static_assert(SOME_TEST<Types_Continuous>::value, "Enum should be …
17 c++  c++11  c++14  c++17  c++20 

1
任何用constexpr string_view替换全局const char []的陷阱吗?
我们的团队正在使用具有10多年历史的C ++代码库,并且最近切换到了C ++ 17编译器。因此,我们正在寻找使代码现代化的方法。在YouTube的一次会议演讲中,我听到了用替换const char*全局字符串的建议constexpr string_view。 由于我们的代码中有很多这样的const char*全局字符串常量,因此我想问一下是否需要了解一些陷阱或潜在问题?

1
std :: pair <自动,自动>返回类型
我玩弄auto在std::pair。在下面的代码中,函数f应该返回std::pair依赖于模板参数的类型的。 一个工作示例: 例1 template &lt;unsigned S&gt; auto f() { if constexpr (S == 1) return std::pair{1, 2}; // pair of ints else if constexpr (S == 2) return std::pair{1.0, 2.0}; // pair of doubles else return std::pair{0.0f, 0.0f}; // pair of floats } 这适用于gcc 9.2,gcc 10.0,clang 9.0和clang 10.0。 接下来,std::pair出于清楚的原因,我想显式地将返回类型编写为: 例子2 …

1
C ++编译器如何找到extern变量?
我用g ++和clang ++编译该程序。有一个区别: g ++打印1,而clang ++打印2。 似乎 g ++:extern变量在最短范围内定义。 clang ++:extern变量是在最短的全局范围内定义的。 C ++规范对此有任何规范吗? main.cpp #include &lt;iostream&gt; static int i; static int *p = &amp;i; int main() { int i; { extern int i; i = 1; *p = 2; std::cout &lt;&lt; i &lt;&lt; std::endl; } } other.cpp int i; 版本:g …

1
__func__指针的两个constexpr实例的区别是否仍然是constexpr?
这是有效的C ++吗? int main() { constexpr auto sz = __func__ - __func__; return sz; } GCC和MSVC认为可以,而Clang认为不可以:Compiler Explorer。 所有编译器都同意这是可以的:Compiler Explorer。 int main() { constexpr auto p = __func__; constexpr auto p2 = p; constexpr auto sz = p2 - p; return sz; } Clang再次不喜欢这个,但是其他的都可以:Compiler Explorer int main() { constexpr auto p …

1
这是std :: gcd中的错误吗?
我遇到了这种std::gcd意外的行为: #include &lt;iostream&gt; #include &lt;numeric&gt; int main() { int a = -120; unsigned b = 10; //both a and b are representable in type C using C = std::common_type&lt;decltype(a), decltype(b)&gt;::type; C ca = std::abs(a); C cb = b; std::cout &lt;&lt; a &lt;&lt; ' ' &lt;&lt; ca &lt;&lt; '\n'; std::cout &lt;&lt; …

5
如何使参数包成组折叠或成对折叠?
template&lt;class Msg, class... Args&gt; std::wstring descf(Msg, Args&amp;&amp;... args) { std::wostringstream woss; owss &lt;&lt; Msg &lt;&lt; ". " &lt;&lt; ... &lt;&lt; " " &lt;&lt; args &lt;&lt; ": '" &lt;&lt; args &lt;&lt; "' ";//not legal at all //or owss &lt;&lt; Msg &lt;&lt; ". " &lt;&lt; args[0] &lt;&lt; ": '" &lt;&lt; args[1] &lt;&lt; …

2
GCC9是否避免了std :: variant的无值状态?
我最近关注了Reddit的讨论,该讨论使std::visit编译器之间的优化有了很好的比较。我注意到以下内容:https : //godbolt.org/z/D2Q5ED 当所有类型都满足某些条件时,GCC9和Clang9(我猜它们共享相同的stdlib)都不会生成用于检查并抛出无值异常的代码。这导致更好的代码生成方式,因此我提出了MSVC STL的问题,并向其提供了以下代码: template &lt;class T&gt; struct valueless_hack { struct tag {}; operator T() const { throw tag{}; } }; template&lt;class First, class... Rest&gt; void make_valueless(std::variant&lt;First, Rest...&gt;&amp; v) { try { v.emplace&lt;0&gt;(valueless_hack&lt;First&gt;()); } catch(typename valueless_hack&lt;First&gt;::tag const&amp;) {} } 声称是,这使得任何变体都没有价值,并且阅读文档应该: 首先,销毁当前包含的值(如果有)。然后直接初始化包含的值,就像T_I使用参数构造类型的值一样。如果std::forward&lt;Args&gt;(args)....引发异常,则*this可能变为valueless_by_exception。 我不明白的是:为什么将其表示为“可能”?如果整个操作失败,保持旧状态合法吗?因为这是GCC的工作: // For suitably-small, trivially copyable types we …

1
std :: vector范围构造函数可以调用显式转换吗?
以下程序格式正确吗? #include &lt;vector&gt; struct A { explicit A(int) {} }; int main() { std::vector&lt;int&gt; vi = {1, 2, 3, 4, 5}; std::vector&lt;A&gt; va(vi.begin(), vi.end()); } 根据C ++ 17 [sequence.reqmts],对于 X u(i, j); X序列容器在哪里,是: T应EmplaceConstructible为X从*i。 但是,在上段中指出: i并j表示满足输入迭代器要求的迭代器,并且是指可隐式转换为的元素value_type, 因此,在我看来,这两个要求都必须满足:范围的值类型必须隐式转换为容器的值类型,并且 EmplaceConstructible必须满足(这意味着分配器必须能够执行所需的初始化) 。由于int不能隐式转换为A,因此该程序应格式错误。 但是,令人惊讶的是,它似乎可以在GCC下进行编译。
14 c++  c++17 

1
为什么std :: swap在Clang / Win下的vector <bool>元素上不起作用?
我有这样的代码: #include &lt;vector&gt; #include &lt;utility&gt; int main() { std::vector&lt;bool&gt; vb{true, false}; std::swap(vb[0], vb[1]); } 关于是否理智的争论,在vector&lt;bool&gt;以下方面效果很好: Mac版Clang Windows的Visual Studio 适用于Linux的GCC 然后,我尝试在Windows上使用Clang构建它,并收到以下错误(摘要): error: no matching function for call to 'swap' std::swap(vb[0], vb[1]); ^~~~~~~~~ note: candidate function [with _Ty = std::_Vb_reference&lt;std::_Wrap_alloc&lt;std::allocator&lt;unsigned int&gt; &gt; &gt;, $1 = void] not viable: expects an l-value for …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.