相关疑难解决方法(0)

C++模板Turing-complete?

我被告知C++中的模板系统在编译时是图灵完备的.这篇文章以及维基百科都提到了这一点.

你能提供一个利用这个属性的计算的重要例子吗?

这个事实在实践中有用吗?

c++ templates turing-complete template-meta-programming

100
推荐指数
9
解决办法
3万
查看次数

为什么名称的声明点在其初始值设定项之前?

Sayeth C++ 标准:

声明的点的名称是立即其完整的说明符后,其之前 初始化(如果有的话)... [basic.scope.pdecl]

也就是说,一个变量在其自身的初始化表达式的上下文中,并且可以被引用。

据我所知,你可以用它做以下类型的事情:

  1. int x = x,这是格式良好但毫无意义。
  2. void* p = &p,这很可爱但没用。
  3. std::any a {&a},#2 的 C++17 版本。
  4. MyClass m {std::move(m)}中,C ++ 11版本的#1和可能UB莫名其妙
  5. MyClass m {myFunc(m)},用一个函数来获取你未初始化的对象,我想把它记录在某个地方?并返回一些值,以便构造函数可以试一试。

#1-4当然没用。似乎可以构建一个接口,其中 #5 有意义,但我认为它不是完成任何事情的最直接方式。由于在评估初始化程序时新变量尚未初始化,因此读取其值是无用/非法的,并且其地址通常对其初始化并不重要。

(对于将声明点保留到初始化器之后,可以提出一个稍微强一点的案例:int avg = avg(a,b,c)。这不是好的代码,它对任何事情都不是必需的,但它比void* p = &p.更有意义。)

但这不仅仅是关于用例。通常,C++ 会煞费苦心地阻止访问未初始化的对象。例如,它一次设置一个对象的 vtable 一个基类:如果 D 继承自 C 继承自 B,则在 C 的构造函数期间,虚方法将被分派给 C 的实现,而不是 D 的实现。可以查看未初始化对象的常见情况是这种情况,以及(更常见的问题)this在成员初始值设定项表达式中的使用。

因此,我看不到在其初始化程序之前将名称带入范围的用途,并且我可以看到将其延迟到初始化程序之后的明确理由(Stroustrup 也会看到)。鉴于此,C++ 选择的行为是否有明确的点?

c++ language-lawyer

14
推荐指数
1
解决办法
403
查看次数

在这个 C 程序中,由于某种奇怪的原因,代码中的第 5 行打印了 1.799999,这是没有意义的

#include<stdio.h>
void main(){
   printf("%f\n",5/9);  // prints 0.000000
   printf("%f\n",9.0/5.0); // prints 1.800000
   printf("%f\n",5/9);  // prints 1.799999
}
Run Code Online (Sandbox Code Playgroud)

第 5 行值应像第 3 行一样打印 0.000000

我在本地机器和在线编译器中尝试过,结果是相同的

c printf

7
推荐指数
2
解决办法
139
查看次数

C++反向'for'循环

我有一个向量:

std::vector<int> vec = {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

我想做一个反向for循环。它有效,当我写:

for(int i = vec.size() - 1; i >= 0; --i) {
    std::cout << i << std::endl; // 2, 1, 0
}
Run Code Online (Sandbox Code Playgroud)

但是如果我这样写,我会得到一个非常大的数字(比如 18446744073709223794):

for(size_t i = vec.size() - 1; i >= 0; --i) {
    std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是当我写的时候它们都有效:

for(int i = 0; i < vec.size() - 1; ++i) {
    std::cout << i << std::endl; // 1, 2, 3
}

// Or
for(size_t i = 0; i < …
Run Code Online (Sandbox Code Playgroud)

c++ unsigned for-loop

6
推荐指数
2
解决办法
401
查看次数

如何获得隐式转换为较低精度的警告?

void func( int radius ) { ... }
Run Code Online (Sandbox Code Playgroud)

这是这样调用的:

func( 12.4 ); // by user expecting the float to be processed, not realizing there's an implicit conversion
Run Code Online (Sandbox Code Playgroud)

在这种情况下,有没有办法从编译器或运行时环境中获得警告?

c++

6
推荐指数
1
解决办法
90
查看次数

为什么C ++可以“填充”初始化可变大小的数组?

#include <iostream>
using namespace std;
void aa(int n) {
    int test[n] = {0};
}
int main() {
    aa(10);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并得到

error: variable-sized object may not be initialized
Run Code Online (Sandbox Code Playgroud)

#include <iostream>
using namespace std;
void aa(int n) {
    int test[n];
    fill(test,test+10,0);
}
int main() {
    aa(10);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

还可以

我想知道为什么在前一个失败的情况下编译该文件的原因。

c++ arrays stack variable-length-array clang++

5
推荐指数
1
解决办法
94
查看次数

使用 scanf 时给出的标准字不能正确打印

我试图 printf 一个简单的字符串,但我不能。

#include <stdio.h>

int main(){
   char *word;
   scanf("%s", &word);
   printf("%s\n", word);
   return 0;
}
 
Run Code Online (Sandbox Code Playgroud)

当我插入这个词时,我的代码会中断。

它只是停止程序执行,但没有给我任何错误。

我究竟做错了什么?

c

4
推荐指数
1
解决办法
112
查看次数

将右值传递给 std::move 并将右值引用绑定到它会在 ASAN 中生成 stack-use-after-scope 错误

考虑这个代码片段

#include <iostream>
int foo() {
  int a;
  return a;
}
int main() {
  auto &&ret = std::move(foo());
  std::cout << ret;
}
Run Code Online (Sandbox Code Playgroud)

使用ASAN编译g++ -fsanitize=address -fno-omit-frame-pointer -g -std=c++17 main.cpp -o main,运行./main显示错误

==57382==ERROR: AddressSanitizer: stack-use-after-scope on address 0x00016b3cb480 at pc 0x000104a37e68 bp 0x00016b3cb450 sp 0x00016b3cb448
READ of size 4 at 0x00016b3cb480 thread T0
    #0 0x104a37e64 in main main.cpp:8
    #1 0x104a75084 in start+0x200 (dyld:arm64e+0x5084)
Run Code Online (Sandbox Code Playgroud)

但是如果我在 auto 之后删除引用,这段代码可以编译并运行,而不会出现 ASAN 给出的错误。我不明白的是,如果std::move返回对给定对象的引用,那么该对象(foo()在本例中是临时创建的)将在函数调用返回后被销毁std::move,因此无论它是绑定到右值引用还是分配给新值应该无效,因为该临时值在移动操作后已经被销毁,对吗?那么为什么 ASAN 在第二种情况下不会给出错误。

- - …

c++ stdmove

4
推荐指数
2
解决办法
188
查看次数

我在方程式中输入一个双整数,但一直保持为0

我对C编程非常陌生,并且遇到了一个小问题。

我输入0.05作为双精度浮点数,并通过我的解决方案图片中给出的公式运行它,以获取答案0.06242。但是,无论输入什么内容,我都会不断得到0.000000。有人可以向我解释我的代码是否有问题,或者可以解释我在scanf和printf中是否正确使用“%lf”?谢谢。

解决我的问题

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

main(){
    double guess, pow1,pow2,pow3, estimate;
    printf("Type in an initial guess of the root(for this case type 0.05):  ");
    scanf("%lf", &guess);

    printf("Calculating the root estimate using formula from solution...\n");
    pow1 = pow(guess, 3);
    pow2 = 0.165*pow(guess, 2);
    pow3 = 3*pow(guess, 2);

    estimate = guess - ((pow1 - pow2 + 0.0003993) / (pow3 - 0.33*guess));
    printf("Estimate = %lf\n", estimate);
}
Run Code Online (Sandbox Code Playgroud)

c

3
推荐指数
1
解决办法
89
查看次数

为什么我可以传递对 C++ 中未初始化元素的引用?

为什么下面的代码可以编译通过?

class Demo
{
    public:
    Demo() : a(this->a){}
    int& a;
};

int main()
{
    Demo d;
}
Run Code Online (Sandbox Code Playgroud)

在本例中,a是对整数的引用。但是,当我初始化 Demo 时,我传递了一个对尚未初始化的整数引用的引用。为什么会这样编译?

即使int我使用对具有私有默认构造函数的类的引用而不是 ,这仍然可以编译。为什么这是允许的?

c++

3
推荐指数
1
解决办法
217
查看次数