Questions tagged «c++17»

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

3
重载lambda函数
如何重载简单的本地lambda函数? SSE原始问题: #include <iostream> #include <map> void read() { static std::string line; std::getline(std::cin, line); auto translate = [](int idx) { constexpr static int table[8]{ 7,6,5,4,3,2,1,0 }; return table[idx]; }; auto translate = [](char c) { std::map<char, int> table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, …

1
C ++ nullptr实现如何工作?
我很好奇如何nullptr运作。标准N4659和N4849说: 它必须有类型std::nullptr_t; 您不能使用其地址; 它可以直接转换为指针和指向成员的指针; sizeof(std::nullptr_t) == sizeof(void*); 其转换bool为false; 可以将其值转换为与相同的整数类型(void*)0,但不能向后转换; 因此,它基本上是一个常量,其含义与相同(void*)0,但类型不同。我std::nullptr_t在设备上找到的实现,如下所示。 #ifdef _LIBCPP_HAS_NO_NULLPTR _LIBCPP_BEGIN_NAMESPACE_STD struct _LIBCPP_TEMPLATE_VIS nullptr_t { void* __lx; struct __nat {int __for_bool_;}; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;} template <class _Tp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator …

2
如果constexpr在lambda中带有static_assert,哪个编译器正确?
当我们要在中使用时static_assert,if constexpr必须使条件取决于某些模板参数。有趣的是,当代码包装在lambda中时,gcc和clang不同意。 以下代码使用gcc进行编译,但是clang触发断言,即使if constexpr不能为true。 #include <utility> template<typename T> constexpr std::false_type False; template<typename T> void foo() { auto f = [](auto x) { constexpr int val = decltype(x)::value; if constexpr(val < 0) { static_assert(False<T>, "AAA"); } }; f(std::integral_constant<int, 1>{}); } int main() { foo<int>(); } 这里的例子。 它可以很容易地通过用固定False<T>通过False<decltype(x)>。 所以问题是:哪个编译器正确?我认为gcc是正确的,因为中的条件static_assert取决于T,但是我不确定。

1
为什么表达式类型在C ++中的版本之间会发生变化?
我尝试理解C ++的表达式类型,我读的越多,我就越困惑,因为我发现C ++草案很难理解,因此倾向于使用其他资源,但是它们彼此矛盾,或者没有考虑到C ++版本之间的措辞和定义有很大的变化。 在下文中,我指的是以下草案: C ++ 11 [ n3690 ](最终草案) C ++ 17 [ n4659 ](最终草案) C ++ 20 [ n4835 ](当前草案) C++11 3.10左值和右值 ... prvalue(“纯” rvalue)是不是xvalue的rvalue。[示例:调用返回类型不是引用的函数的结果是prvalue。文字的值(例如12、7.3e5或true)也是prvalue。—结束示例] C++17 3.10左值和右值 ... prvalue是一个表达式,其求值初始化一个对象或位域,或计算一个运算符的操作数的值,该值由其出现的上下文指定。 C++20 7.2.1值类别* ... prvalue是一个表达式,其求值初始化一个对象或位字段,或者计算一个运算符的操作数(由其出现的上下文指定),或者是cv void类型的表达式。 我会理解措词的更改,并进行了一些调整,但对我而言,整个定义都会更改。有人可以帮我理解吗?例如,为什么删除了一个句子,即prvalue是不是xvalue的rvalue?还是为什么删除了有用的示例?
13 c++  c++11  c++14  c++17  c++20 

1
gcc中的模糊运算符
我制作了一个用于打印一些stl容器的功能模板 #include <iostream> #include <vector> #include <string> template <template <typename, typename> class C, typename T, typename A> std::ostream& operator<<(std::ostream& os, const C<T, A>& container) { for (auto& elem : container) { os << elem << " "; } return os; } int main() { std::vector<std::string> v { "One", "Two", "Three" …
13 c++  c++17 

2
是否可以在编译时连接两个类型为const char *的字符串?
显然,我们可以在一个constexpr函数中连接两个字符串文字,但是如何将一个字符串文字与另一个constexpr函数返回的字符串连接起来呢,如下面的代码所示? template <class T> constexpr const char * get_arithmetic_size() { switch (sizeof(T)) { case 1: return "1"; case 2: return "2"; case 4: return "4"; case 8: return "8"; case 16: return "16"; default: static_assert(dependent_false_v<T>); } } template <class T> constexpr std::enable_if_t<std::is_arithmetic_v<T>, const char *> make_type_name() { const char * …
12 c++  c++17 

1
原始static_vector实现中可能的未定义行为
tl;博士:我认为我的static_vector具有未定义的行为,但我找不到它。 这个问题是在Microsoft Visual C ++ 17上实现的。我有一个简单而未完成的static_vector实现,即一个具有固定容量的矢量,可以堆栈分配。这是一个C ++ 17程序,使用std :: aligned_storage和std :: launder。我试图将其归结为以下我认为与该问题相关的部分: template <typename T, size_t NCapacity> class static_vector { public: typedef typename std::remove_cv<T>::type value_type; typedef size_t size_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; static_vector() noexcept : count() { } ~static_vector() { …

1
标准是否保证无捕获的lambda为空?
我正在寻找一种从模板函数中的其他lambda识别空(无捕获)lambda的方法。我目前正在使用C ++ 17,但我也对C ++ 20的答案感到好奇。 我的代码如下所示: template<typename T> auto func(T lambda) { // The aguments of the lambdas are unknown if constexpr (/* is captureless */) { // do stuff } } C ++标准(17或20)是否保证可转换为函数指针的不可捕获lambda也会使std::is_emptyyield 变为true? 以以下代码为例: auto a = []{}; // captureless auto b = [c = 'z']{}; // has …
12 c++  lambda  c++17  c++20 

1
使std :: vector分配内存的现代方法
在以下问题是相关的,但答案是旧的,并且从用户评论马克Glisse表明有因为C ++ 17的新方法这个问题可能没有得到充分讨论。 我正在尝试使对齐的内存对于SIMD正常工作,同时仍然可以访问所有数据。 在Intel上,如果创建类型为float的向量__m256,并将大小减小8倍,则会使内存对齐。 例如 std::vector<__m256> mvec_a((N*M)/8); 以一种有点怪异的方式,我可以将指向矢量元素的指针强制转换为float,这使我可以访问各个float值。 取而代之的是,我希望具有一个std::vector<float>正确对齐的,因此可以在__m256不进行段错误的情况下加载到其他SIMD类型中。 我一直在研究aligned_alloc。 这可以给我一个正确对齐的C样式数组: auto align_sz = static_cast<std::size_t> (32); float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float)); 但是我不确定如何执行此操作std::vector<float>。赋予std::vector<float>所有权marr_a 似乎是不可能的。 我已经看到一些建议,我应该编写一个自定义分配器,但这似乎需要大量工作,也许对于现代C ++,有更好的方法吗?

1
不合格的sort()—为什么在std :: vector而不是std :: array上使用时会编译,并且哪个编译器正确?
呼叫std::sort()时std::array: #include <vector> #include <array> #include <algorithm> int main() { std::vector<int> foo{4, 1, 2, 3}; sort(begin(foo), end(foo)); std::array<int, 4> foo2{4, 1, 2, 3}; sort(begin(foo2), end(foo2)); } gcc和clang都在std::array--clang说的排序上返回错误 错误:使用未声明的标识符“ sort”;您是说'std :: sort'吗? 进行更改以std::sort(begin(foo2), end(foo2))解决问题。 MSVC按照编写的方式编译上面的代码。 std::vector和之间为什么区别对待std::array; 哪个编译器正确?
11 c++  c++17 

1
在C ++ 17中初始化后可以更改内联变量吗?
我的情况如下(它在clang中起作用,但在gcc中不起作用) liba.hpp: inline int MY_GLOBAL = 0; libother.cpp:(dll) #include "myliba.hpp" void myFunc() { // MYGLOBAL = 28; } someexe.cpp: RunAppThatUsesBothLibAandLibOther(); 问题在于,内联变量在我希望28的地方显示0,因为它在运行时被修改了。MSVC对此表示不同意,但是clang做了我期望的事情。 问题是:在我的方案中,可以在运行时修改内联变量吗?(我通过取消内联变量解决了问题。)
11 c++  visual-c++  dll  clang  c++17 

6
基于无辜范围的循环无效
以下内容无法编译: #include <iostream> int main() { int a{},b{},c{},d{}; for (auto& s : {a, b, c, d}) { s = 1; } std::cout << a << std::endl; return 0; } 在Godbolt上尝试 编译器错误是: error: assignment of read-only reference 's' 现在,在我的实际情况中,列表由类中的成员变量组成。 现在,这不起作用,因为表达式变为initializer_list<int>实际上复制a,b,c和d的a,因此也不允许修改。 我的问题有两个: 不允许以这种方式编写基于范围的for循环背后有动机吗? 例如。也许会有一些特殊的情况来表达裸括号。 修复此类循环的语法整洁方法是什么? 最好遵循以下方式: for (auto& s : something(a, b, …

2
weak_ptr重置会影响shared_ptr吗?
我不习惯使用它weak_ptr,我正面临一个令人困惑的情况。我正在将Intel XE 2019 Composer更新5(程序包2019.5.281)与Visual Studio 2019版本结合使用。16.2.5。我用64位编译。我使用标准的C ++ 17。 这是我的秒杀解决方案的代码: #include <memory> #include <iostream> using namespace std; int main( int argc, char* argv[] ) { shared_ptr<int> sp = make_shared<int>( 42 ); cout << "*sp = " << *sp << endl; weak_ptr<int> wp = sp; cout << "*sp = " << *sp …

3
我可以在并行执行策略中使用std :: transform吗?
如果我没有记错的话,我可以std::transform执行到位 ,通过使用同一范围内的输入和输出迭代器。假设我有一些std::vector对象vec,那么我会写 std::transform(vec.cbegin(),vec.cend(),vec.begin(),unary_op) 使用合适的一元运算unary_op。 使用C ++ 17标准,我想通过std::execution::par在其中插入第一个参数来并行执行转换。这会使该函数从上cppreference文章std::transform中的重载(1)变为(2)。但是,对此超载的注释说: unary_op[...]不得使任何迭代器(包括最终迭代器)无效,或修改所涉及范围的任何元素。(自C ++ 11起) “修改任何元素”真的意味着我无法就地使用算法,还是在谈论我误解的其他细节?

1
GCC / C ++ 17中带有模板模板类的问题
考虑以下2个重载 template<typename T> bool test() { return true; } template<template<typename ...> class T> bool test() { return false; } 第一个适用于常规类,而第二个适用于未实例化的模板。例如: std::cout<<test<int>()<<std::endl; <-- this yields 1 std::cout<<test<std::list>()<<std::endl; <--this yields 0 现在考虑以下模板函数: template<typename U> bool templfun(){ struct A{ bool f(){ return test<A>(); // <-- this gives an error } }; return test<A>(); …
10 c++  templates  gcc  clang  c++17 

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.