Questions tagged «c++»

C ++是一种通用编程语言。它最初被设计为C的扩展,并且具有类似的语法,但是现在它是一种完全不同的语言。使用此标记可解决有关将要使用C ++编译器编译的代码的问题。对于与特定标准修订版[C ++ 11],[C ++ 14],[C ++ 17]或[C ++ 20]等相关的问题,请使用特定于版本的标记。

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

2
复制和移动构造函数自动成为朋友吗?
当我们定义复制或移动构造函数时,我们可以访问另一个类的私有变量。C ++是否会friend自动使它们彼此交互? 例如: my_str::my_str(my_str&& m) { size_ = m.size_; //accessing private variable another my_str class buff_ = m.buff_; //accessing private variable another my_str class m.buff_ = nullptr; m.size_ = 0; }
14 c++  friend-class 

2
如果琐碎的默认构造函数不执行任何操作,为什么不能使用malloc创建琐碎的可构造对象?
我很难理解cppreference引用的有关普通默认构造函数的以下段落。我已经搜索了stackoverflow,但仍然没有一个明确的答案。所以请帮忙。 普通的默认构造函数是不执行任何操作的构造函数。与C语言兼容的所有数据类型(POD类型)都是默认可构造的。但是,与C语言不同,不能通过简单地重新解释适当对齐的存储来创建具有琐碎默认构造函数的对象,例如,用std :: malloc分配的内存:正式引入新对象并避免潜在的未定义行为时,需要placement-new。 具体来说,如果琐碎的默认构造函数什么都不做,为什么我们不能重新解释存储并假装存在具有给定类型的对象?您能否提供一些可能导致未定义行为的示例?

3
为什么数组的维是其类型的一部分?
在阅读C ++ Primer书籍时,我遇到了这样的说法:“数组中元素的数量是数组类型的一部分。” 因此,我想使用以下代码进行查找: #include<iostream> int main() { char Array1[]{'H', 'e', 'l', 'p'}; char Array2[]{'P', 'l', 'e', 'a', 's', 'e'}; std::cout<<typeid(Array1).name()<<std::endl; //prints A4_c std::cout<<typeid(Array2).name()<<std::endl; //prints A6_c return 0; } 有趣的是,两个数组上的typeid结果表明它们有所不同。 幕后发生了什么事? 为什么数组必须具有包含其大小的类型?仅仅是因为它的大小不应该改变吗? 这将如何影响比较数组? 只是希望能够深刻理解这个概念。
14 c++  arrays  c++11 

3
脱机成员函数定义是否需要使用低于全球范围的完全限定的类名?
这个问题让我想知道在类外成员函数定义中完全限定类名(包括全局作用域运算符)是否有用/必需。 一方面,我以前从未见过这样做(正确执行的语法似乎还不清楚)。另一方面,C ++名称查找非常简单,因此可能存在一个极端情况。 题: 是否曾经有过引入超出成员函数定义的定义 ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... } 不同于 ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... }(没有全局作用域::前缀)的情况? 请注意,成员函数定义必须放在封闭类的名称空间中,因此这不是有效的示例。

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

3
为什么(++ i)++有效,“ ++ i ++”无效?
让我们考虑以下代码: int main() { int i = 2; int b = ++i++; return 3; } 编译时出现以下错误: <source>: In function 'int main()': <source>:3:16: error: lvalue required as increment operand 3 | int b = ++i++; | ^~ 这对我来说听起来很公平。后缀递增的优先级高于前缀递增的优先级,因此代码被解析为int b = ++(i++);,i是一个右值。因此,错误。 现在,让我们考虑带有括号的此变体,以覆盖默认优先级: int main() { int i = 2; int b …

1
std :: vector范围构造函数可以调用显式转换吗?
以下程序格式正确吗? #include <vector> struct A { explicit A(int) {} }; int main() { std::vector<int> vi = {1, 2, 3, 4, 5}; std::vector<A> 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 

2
了解对象是否为整数或类类型有什么意义?
您好,我在Cppreference.com上看到了许多这样的示例: std::is_class<T> std::is_integral 等等。我知道我是否例如运行代码get true或false。但是,这有什么意义呢?例如知道对象是否为类类型? #include <iostream> #include <type_traits> struct A {}; class B {}; enum class C {}; int main() { std::cout << std::boolalpha; std::cout << std::is_class<A>::value << '\n'; std::cout << std::is_class<B>::value << '\n'; std::cout << std::is_class<C>::value << '\n'; std::cout << std::is_class<int>::value << '\n'; } 输出: true true false …
14 c++  templates 

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 …

3
重载lambda函数
如何重载简单的本地lambda函数? SSE原始问题: #include &lt;iostream&gt; #include &lt;map&gt; 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&lt;char, int&gt; table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, …

3
模板函数不适用于采用const ref的指针到成员函数
最近,我编写了一个模板函数来解决一些代码重复。看起来像这样: template&lt;class T, class R, class... Args&gt; R call_or_throw(const std::weak_ptr&lt;T&gt;&amp; ptr, const std::string&amp; error, R (T::*fun)(Args...), Args... args) { if (auto sp = ptr.lock()) { return std::invoke(fun, *sp, args...); } else { throw std::runtime_error(error.c_str()); } } int main() { auto a = std::make_shared&lt;A&gt;(); call_or_throw(std::weak_ptr&lt;A&gt;(a), "err", &amp;A::foo, 1); } 这段代码非常适合class A如下所示: …
14 c++  templates 

3
std :: bit_cast与std :: array
Timur Doumler 在他最近的演讲“现代C ++中的类型修剪”中说,由于不能从函数返回C样式的数组,std::bit_cast因此不能用于将a 强制float转换unsigned char[4]为a。我们应该使用std::memcpy或等到C ++ 23(或更高版本)后,类似的东西reinterpret_cast&lt;unsigned char*&gt;(&amp;f)[i]才能很好地定义。 在C ++ 20中,我们可以在中std::array使用std::bit_cast, float f = /* some value */; auto bits = std::bit_cast&lt;std::array&lt;unsigned char, sizeof(float)&gt;&gt;(f); 而不是C样式的数组来获取float?的字节?

3
复制列表初始化?为什么会编译?
我正在使用Microsoft Visual Studio Community 2019 V16.5.2。我想测试列表初始化 请参阅以下测试程序: #include &lt;string&gt; void foo(std::string str) {} int main() { foo( {"str1", "str2"} ); return 0; } 编译时没有错误和警告。为什么? 它给出了运行时错误: Expression: Transposed pointer range 有人可以解释一下这里发生了什么吗? 编辑。 我反汇编了代码并在调试器中运行 foo( {"str1", "str2"} ); 00F739A8 sub esp,1Ch 00F739AB mov esi,esp 00F739AD mov dword ptr [ebp-0C8h],esp 00F739B3 lea ecx,[ebp-0D1h] …
13 c++ 

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 &lt;class _Tp&gt; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator …

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.