Questions tagged «c++»

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


4
为什么派生类不能在此代码中调用受保护的成员函数?
#include <iostream> class Base { protected: void somethingProtected() { std::cout << "lala" << std::endl; } }; class Derived : public Base { public: void somethingDerived() { Base b; b.somethingProtected(); // This does not compile somethingProtected(); // But this is fine } }; int main() { Derived d; d.somethingDerived(); return 0; …
67 c++  oop 

2
此模板代码如何获得数组的大小?
我想知道为什么这种代码可以得到测试数组的大小?我对模板中的语法不熟悉。也许有人可以解释下代码的含义template<typename,size_t>。此外,参考链接也是首选。 #define dimof(array) (sizeof(DimofSizeHelper(array))) template <typename T, size_t N> char(&DimofSizeHelper(T(&array)[N]))[N]; void InitDynCalls() { char test[20]; size_t n = dimof(test); printf("%d", n); }
61 c++  visual-c++ 

10
C ++中的签名溢出和未定义的行为(UB)
我想知道以下代码的使用 int result = 0; int factor = 1; for (...) { result = ... factor *= 10; } return result; 如果循环是随着n时间反复进行的,则将factor其乘以10精确的n时间。但是,factor仅在相乘10了总n-1次数后才使用。如果我们假设factor除了在循环的最后一次迭代中永远不会溢出,而是可能在循环的最后一次迭代中溢出,那么这样的代码是否可以接受?在这种情况下,factor证明溢出后永远不会使用的值。 我正在就是否应接受此类代码进行辩论。可以将乘法放在if语句中,并且在可能溢出时,不对循环的最后一次迭代进行乘法。缺点是它会使代码混乱,并添加了一个不必要的分支,需要在所有先前的循环迭代中进行检查。我还可以减少循环迭代一次,并在循环之后复制一次循环主体,这又使代码复杂化。 有问题的实际代码在一个紧密的内部循环中使用,该循环在实时图形应用程序中消耗大量的总CPU时间。

5
如何在Lambda本身中获取C ++ Lambda函数的地址?
我试图弄清楚如何获取自身内部的lambda函数的地址。这是一个示例代码: []() { std::cout << "Address of this lambda function is => " << ???? }(); 我知道我可以在变量中捕获lambda并打印地址,但是我想在执行此匿名函数时就地执行该操作。 有没有更简单的方法?
53 c++  c++11  lambda  c++14  c++17 

3
没有为C ++ 20中的自定义太空飞船运算符实现定义平等运算符
我<=>在C ++ 20中使用新的宇宙飞船运算符遇到一种奇怪的行为。我正在将Visual Studio 2019编译器与一起使用/std:c++latest。 这段代码可以正常编译: #include <compare> struct X { int Dummy = 0; auto operator<=>(const X&) const = default; // Default implementation }; int main() { X a, b; a == b; // OK! return 0; } 但是,如果我将X更改为: struct X { int Dummy = 0; auto operator<=>(const X& …

3
使用一个函数调用C ++初始化多个常量类成员
如果我有两个不同的常量成员变量,都需要基于相同的函数调用进行初始化,是否有一种方法可以在不两次调用函数的情况下进行? 例如,分数类,其中分子和分母是常数。 int gcd(int a, int b); // Greatest Common Divisor class Fraction { public: // Lets say we want to initialize to a reduced fraction Fraction(int a, int b) : numerator(a/gcd(a,b)), denominator(b/gcd(a,b)) { } private: const int numerator, denominator; }; 由于两次调用GCD函数,这会浪费时间。您还可以定义一个新的类成员,gcd_a_b然后首先将gcd的输出分配给初始化程序列表中的输出,但这将导致内存浪费。 通常,有没有一种方法可以避免浪费的函数调用或内存?您能否在初始化列表中创建临时变量?谢谢。

5
在C ++中将模板友好字符串转换为数字
在C ++标准库中,有一些函数可以将字符串转换为数字类型: stoi stol stoll stoul stoull stof stod stold 但是我发现在模板代码中使用它们很麻烦。为什么没有模板功能,例如: template<typename T> T sto(...) 将字符串转换为数字类型? 我看不出没有它们的任何技术原因,但也许我缺少了一些东西。它们可以专门用于调用基础的命名函数,并使用enable_if/ concepts禁用非数字类型。 标准库中是否有任何模板友好的替代方法,可以将字符串转换为数字类型,并且以有效的方式将其转换?

2
为什么是“使用系统”;不算作坏习惯吗?
我具有C ++背景,并且我完全理解并同意以下问题的答案:为什么“使用命名空间标准”;被认为是不良做法? 因此,令我惊讶的是,现在已经有了C#的经验,我看到了与之完全相反的地方: using Some.Namespace;确实在任何地方都使用过。无论何时开始使用类型,都首先为其名称空间添加using指令(如果尚不存在)。我不记得曾经看到过一个.cs不是以-开头的文件using System; using System.Collections.Generic; using X.Y.Z; etc...。实际上,如果您通过Visual Studio向导添加了新文件,即使您根本不需要它们,它也会在其中自动添加一些using指令。因此,尽管在C ++社区中您基本上被私刑了,但C#甚至鼓励这样做。至少我是这样。 现在,我知道在C#和C ++中使用指令并不完全相同。另外,我确实知道,using namespace在C ++中可以做的最讨厌的事情之一,即将其放入头文件中,由于缺少头文件和的概念,因此在C#中没有同等讨厌的对象#include。 但是,尽管它们有所不同,但在C#和C ++中使用伪指令却达到了相同的目的,即仅需SomeType始终键入,而不必花更长的时间Some.Namespace.SomeType(在C ++中使用::代替.)。出于同样的目的,危险对我来说似乎也一样:命名碰撞。 在最佳情况下,这会导致编译错误,因此您“仅”必须进行修复。在最坏的情况下,它仍然会编译,并且代码会静默地执行与您预期的不同的操作。所以我的问题是:为什么(显然)使用的指令在C#和C ++中被认为是同等糟糕的? 我有一些答案的想法(尽管这些想法都没有真正让我满意): 命名空间趋向于更长和更嵌套在C#比在C ++(std对比System.Collection.Generic)。因此,以这种方式对代码进行降噪会有更多的愿望和收获。但是,即使这是真的,该参数也仅在我们查看标准名称空间时适用。自定义名称可以在C#和C ++中具有您喜欢的任何短名称。 在C#中,命名空间似乎比在C ++中更“精细”。举个例子,在C ++整个标准库包含在std(加上一些微小的嵌套的命名空间一样chrono),而在C#中你有System.IO,System.Threading,System.Text等,所以,其命名冲突的风险较小。但是,这只是一种直觉。实际上,我没有计算您使用using namespace std和导入的名称using System。同样,即使这是正确的,此参数也仅在查看标准名称空间时适用。您可以在C#和C ++中将自己的代码设计为细粒度。 还有更多争论吗?我对实际的硬事实(如果有的话)特别感兴趣,而对观点却不太感兴趣。

2
查找A xor X = B + X的解的算法
给定整数A和B,找到整数X以便: A,B <2 * 1e18 A xor X = B + X 我非常怀疑是否可以使用数学方法来解决这个方程。这是我3年前遇到的编码问题,即使现在我自己也无法解决。 到目前为止,我的代码:(这是蛮力解决方案) #include <iostream> using namespace std; int main() { unsigned long long a, b; cin >> a >> b; for (unsigned long long x = 1; x < max(a, b); x++) { unsigned long long c = …
46 c++  xor 

3
std :: vector(ab)使用自动存储
考虑以下代码段: #include <array> int main() { using huge_type = std::array<char, 20*1024*1024>; huge_type t; } 显然,它将在大多数平台上崩溃,因为默认堆栈大小通常小于20MB。 现在考虑以下代码: #include <array> #include <vector> int main() { using huge_type = std::array<char, 20*1024*1024>; std::vector<huge_type> v(1); } 令人惊讶的是它也崩溃了!追溯(使用最新的libstdc ++版本之一)指向include/bits/stl_uninitialized.h文件,我们可以在其中看到以下几行: typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; std::fill(__first, __last, _ValueType()); 调整大小的vector构造函数必须默认初始化元素,这就是它的实现方式。显然,_ValueType()临时崩溃会使堆栈崩溃。 问题是这是否是符合标准的实现。如果是,那么实际上意味着使用巨大类型的向量是非常有限的,不是吗?

3
如何在编译时获取多维std :: vector的深度?
我有一个函数,需要一个多维参数std::vector,需要将深度(或维数)作为模板参数传递。与其对这个值​​进行硬编码,我想编写一个constexpr函数,该函数将std::vector并将深度作为unsigned integer值返回。 例如: std::vector<std::vector<std::vector<int>>> v = { { { 0, 1}, { 2, 3 } }, { { 4, 5}, { 6, 7 } }, }; // Returns 3 size_t depth = GetDepth(v); 不过,这需要在编译时完成,因为此深度将作为模板参数传递给模板函数: // Same as calling foo<3>(v); foo<GetDepth(v)>(v); 有什么办法吗?

2
为什么对于许多标准库类型在C ++ 20中删除了operator!=?
根据cppreference,std::type_info::operator!=被C ++ 20删除,但是std::type_info::operator==显然仍然存在。 背后的原因是什么?我可能同意比较不平等是没有意义的,但是比较相等也同样是没有意义的,不是吗? 同样,operator!=在许多其他标准库类型中,包括容器,例如std::unordered_map::operator!=和,std::unordered_set::operator!=将根据cppreference在C ++ 20中将其删除。 相比之下,必须编写if(!(id1 == id2))并不会使任何代码更清晰if(id1 != id2),相反,相反……

5
是否可以防止省略聚合初始化成员?
我有一个结构,其中有许多相同类型的成员,像这样 struct VariablePointers { VariablePtr active; VariablePtr wasactive; VariablePtr filename; }; 问题是,如果我忘了初始化一个结构成员(例如wasactive),就像这样: VariablePointers{activePtr, filename} 编译器不会抱怨它,但是我将拥有一个部分初始化的对象。如何防止这种错误?我可以添加一个构造函数,但是它将重复两次变量列表,所以我必须键入所有这三次! 如果有针对C ++ 11的解决方案,请同时添加C ++ 11的答案(当前我仅限于该版本)。不过,也欢迎使用最新的语言标准!


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.