我正在阅读《C++ 如何编程》第 9 版,尝试学习 C++,并尝试使用第 7 章中的骑士问题进行练习。
根据输出中的“64”,代码显然存在某种逻辑错误(我将自行修复),但在执行此操作之前,我一直致力于理解以及如何处理编译器警告。
我已将 board 声明为 unsigned int 的二维数组,因为它只能包含值 0-7。同样,出于同样的原因,我将 for 循环中的变量声明为 unsigned int。
我在 stackoverflow 上读过有关此问题的回复,但它们很快就超出了我的理解范围。
#include <iostream>
#include <array>
#include <iomanip>
using namespace std;
void printArray(const array< array< unsigned int, 8 >, 8 >);
int main() {
array< array< unsigned int, 8 >, 8 > board = {};
array< int, 8 > horizontal = {{ 2, 1, -1, -2, -2, -1, 1, 2 }};
array< int, 8 > vertical = {{ -1, -2, …Run Code Online (Sandbox Code Playgroud) 我有一种情况,我需要重载解析来更喜欢带有隐式转换的重载而不是同名的模板函数。
考虑以下示例:
#include <iostream>
#include <functional>
void call_function(const std::function<void()>& function)
{
std::cout << "CALL FUNCTION 1" << std::endl;
function();
}
template <typename Function>
void call_function(const Function& function)
{
std::cout << "CALL FUNCTION 2" << std::endl;
function();
}
int main()
{
// Pass a lambda to "call_function"
// This lambda is implicitly convertible to 'std::function<void()>'
// Even though it is implicitly convertible, the template function is selected by the compiler.
call_function([]{
std::cout << "TEST" << std::endl;
});
}
Run Code Online (Sandbox Code Playgroud)
输出:
CALL FUNCTION …Run Code Online (Sandbox Code Playgroud) 我正在使用https://cppinsights.io/。以下是代码(默认示例)
#include <cstdio>
int main()
{
const char arr[10]{2,4,6,8};
for(const char& c : arr)
{
printf("c=%c\n", c);
}
}
Run Code Online (Sandbox Code Playgroud)
关于cppinsights
C++ Insights 是一个基于 clang 的工具,可以进行源到源的转换。它的目标是让事情可见,这通常是有意地在幕后发生。这是关于编译器为我们做的事情的魔法。或者查看编译器的类。
这是生成的代码,这是编译器如何看待代码
#include <cstdio>
int main()
{
const char arr[10] = {2, 4, 6, 8, '\0', '\0', '\0', '\0', '\0', '\0'};
{
char const (&__range1)[10] = arr;
const char * __begin1 = __range1;
const char * __end1 = __range1 + 10L;
for(; __begin1 != __end1; ++__begin1) {
const char & c = *__begin1;
printf("c=%c\n", …Run Code Online (Sandbox Code Playgroud) 我不确定这个函数指针类型声明语法,但它有效。语法就像声明一个普通的旧函数。
typedef struct Element GetChildCallback(void *userdata, usize parent, usize child_no);
Run Code Online (Sandbox Code Playgroud)
我找不到任何关于它是否符合标准或它可能有哪些缺点的信息。
我认为这仅适用于 typedef,所以我更进一步,发现这也适用于常规函数参数:
extern inline void dmpstrn(const char *t, usize n, int printer(const char *fmt, ...));
inline void dmpstrn(const char *t, usize n, int printer(const char *fmt, ...)) {
usize len = strlen(t) > n ? n : strlen(t);
printer("\"");
for (usize i = 0; i < len; i += 1) {
if (t[i] == '\n')
printer("\\n");
else
printer("%c", t[i]);
}
printer("\"\n");
}
// ...
int main() {
dmpstrn("Hello\nworld", UINT64_MAX, …Run Code Online (Sandbox Code Playgroud) c typedef function-pointers implicit-conversion function-declaration
如果输入数组为空,则array.size()应该为 0。第一个for,从0到array.size() - 1,应该意味着它从0到-1,对吗?
for那么,不应输入此值,并且该函数应返回 inversionsCounter 值,该值将是0
但这并没有发生,代码进入了无限循环。为什么是这样?
这是代码:
#include <vector>
#include <iostream>
using namespace std;
int countInversions(vector<int> array)
{
int inversionsCounter = 0;
for (int i = 0; i < array.size() - 1; ++i)
for (int j = i + 1; j < array.size(); ++j)
if (array[i] > array[j])
++inversionsCounter;
return inversionsCounter;
}
int main()
{
vector<int> array = {};
cout << array.size();
cout << …Run Code Online (Sandbox Code Playgroud) 我想了解如何引用初始化。例如,我们看一个典型的例子。
double val = 4.55;
const int &ref = val;
Run Code Online (Sandbox Code Playgroud)
我可以想到上面代码片段中发生的事情的两种可能性。
通常的解释如下:
这里创建了一个带有值类型的临时(纯右值),然后将引用绑定到这个临时(纯右值)对象,而不是直接绑定到变量。发生这种情况是因为右侧变量的类型是,而左侧我们有一个引用。但是为了将引用绑定到变量,类型应该匹配。此外,临时纯右值的生命周期也得到了延长。int4refintvalvaldoubleint
我认为还有另一种可能发生的情况,如下:
这里创建了一个具有值类型的临时(纯右值)。但由于需要一个左值并且当前我们有一个纯右值,因此临时物化开始,因此纯右值被转换为xvalue。然后引用绑定到这个具体化的 xvalue(因为 xvalue 也是泛左值) ,而不是直接绑定到变量。发生这种情况是因为右侧变量的类型是,而左侧我们有一个引用。但是为了将引用绑定到变量,类型应该匹配。此外,物化临时 xvalue 的生命周期也延长了。int4const int &refrefvalvaldoubleint
我的问题是:
PS:我并不是在寻找解决这个问题的方法。例如,我知道我可以简单地写:
const double …
在 Postgres 14 中,我看到的舍入结果对我来说没有意义。试图了解发生了什么事。在所有情况下,我都会将19除以3。
将任一integer值转换为real:
SELECT 19::real /3;
Run Code Online (Sandbox Code Playgroud)
产生的值为6.333333333333333
SELECT 19/3::real;
Run Code Online (Sandbox Code Playgroud)
产生的值为6.333333333333333
然而,将双方都转换为real产量:
SELECT 19::real/3::real;
Run Code Online (Sandbox Code Playgroud)
产生的值为6.3333335
有趣的是,如果我将两边都转换为double precisionor float,答案是6.333333333333333
还
SELECT 19.0 / 3.0;
Run Code Online (Sandbox Code Playgroud)
产量6.333333333333333
SELECT 19.0::real / 3.0::real;
Run Code Online (Sandbox Code Playgroud)
产量6.3333335
SELECT ( 16.0 / 3.0) :: real;
Run Code Online (Sandbox Code Playgroud)
产量6.3333335
我现在看到:
SELECT 6.333333333333333::real;
Run Code Online (Sandbox Code Playgroud)
产量6.33333335
所以真正的问题似乎是:
为什么我们以这种奇怪的方式四舍五入(我知道实数/浮点数是不精确的,但这似乎很极端。)
数据类型是什么19::real / 3;
postgresql floating-point rounding type-conversion implicit-conversion
跟进我的问题c++ - 使用中间类型时隐式转换如何工作?,从中我了解了1 隐式转换 max的规则,我试图了解涉及函数参数的更高级用例。
假设我有一个函数,它接受另一个函数作为参数。该函数参数可以返回某些内容,也可以不返回任何内容(void)。因此,我想重载函数定义,在一种情况下接受非 void 函数参数,在另一种情况下接受 void 函数参数。
using VoidType = void (string);
using NonVoidType = string (string);
string call(VoidType *fn, string arg) {
cout << "[using void function]" << endl;
fn(arg);
return arg;
}
string call(NonVoidType *fn, string arg) {
cout << "[using non void function]" << endl;
return fn(arg);
}
Run Code Online (Sandbox Code Playgroud)
调用函数时,给定参数具有已知类型,因此重载选择应该很简单,如下所示:
void printVoid(string message) {
cout << message << endl;
}
string printNonVoid(string message) {
cout << message << endl;
return message;
} …Run Code Online (Sandbox Code Playgroud) 我读了很多关于这个主题的回复,但我仍然无法理解。请理解我正在学习过程中。
有人告诉我,向量只不过是它的第一个元素地址,因此是一个二维向量。
那么,为什么如果我通过指针传递 2D 向量,我就会失去使用索引的能力。
int vec[10][10] = { 1, 2, 3, 4 };
int *v = vec;
Run Code Online (Sandbox Code Playgroud)
为什么我不能说
int a = v[1][1]
Run Code Online (Sandbox Code Playgroud)
就像我会做的那样
int a = vec[1][1]
Run Code Online (Sandbox Code Playgroud)
if v,那是一个指向int, 的指针,而vec, 那是一个指向int, 的指针,那么它们不是完全相同的东西,同一个对象吗?
我读到
int (*v)[N] = vec;
Run Code Online (Sandbox Code Playgroud)
其中N是列数。但这对于初学者来说似乎是一件超级棘手的事情。
为什么是这样?
编辑:
我的大脑想到了这个解释,int (*vec)[N]解释了指向向量 10 的指针的int含义。这里是。
鉴于我的理解,在二维数组中,指向第一个元素的指针是指向N元素数组的指针,这是我给自己的解释。
如果 lhs ofint *var = &int必须从右到左读取,变成“ varis a pointerto int”,那么我期望int [N] …
我有一个类,其中一个二维数组的int实现为int**.我按如下方式为这个2D数组实现了一个访问器函数,返回一个const int**以防止用户编辑它:
const int** Class::Access() const
{
return pp_array;
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了编译错误"从int**到const int**的无效转换".为什么不允许在这里推广const?如何在不编辑权限的情况下授予用户访问信息的权限?