小编use*_*570的帖子

std::is_same 编译器之间的不同结果

#include <iostream>

int main() {
    bool b = true;
    std::cout << std::is_same<decltype(!(!b)), bool>::value << "\n";

    auto bb = (!(!b));
    std::cout << std::is_same<decltype(bb), bool>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)

上面的代码使用不同的编译器有不同的结果。这是编译器错误还是我遗漏了什么?

c++ boolean rvalue lvalue value-categories

58
推荐指数
1
解决办法
2408
查看次数

C++ 中所有指针的大小都相同吗?

最近,我看到这样的说法

所有指针具有相同的大小是很常见的,但从技术上讲,指针类型具有不同的大小是可能的

但后来我发现了这样的内容:

虽然指针的大小都是相同的,因为它们只存储内存地址,但我们必须知道它们指向什么类型的东西。

现在,我不确定以上哪种说法是正确的。第二个引用的语句看起来像是来自佛罗里达州立大学计算机科学的 C++ 笔记。


这就是为什么在我看来所有指针都应该具有相同的大小:

1)假设我们有:

int i = 0;
void* ptr = &i; 
Run Code Online (Sandbox Code Playgroud)

现在,假设 C++ 标准允许指针具有不同的大小。进一步假设在某些任意机器/编译器上(因为标准允许),a 的void*大小为 2 字节,而 a 的int*大小为 4 字节。

现在,我认为这里有一个问题,即右侧有一个int*大小为 4 字节的 ,而左侧有一个void*大小为 2 字节的 。int*因此,当从到发生隐式转换时,void*将会丢失一些信息

2)所有指针都保存地址。由于对于给定的机器,所有地址都具有相同的大小,因此所有指针也应该具有相同的大小是非常自然(合乎逻辑的)。

因此,我认为第二句话是正确的。


我的第一个问题是 C++ 标准对此有何规定?

我的第二个问题是,如果 C++ 标准确实允许指针具有不同的大小,那么有理由吗?我的意思是允许指针具有不同的大小对我来说似乎有点不自然(考虑到我上面解释的两点)。所以,我很确定标准委员会一定已经考虑到了这一点(指针可以有不同的大小),并且已经有理由允许指针有不同的大小。请注意,只有当标准确实允许指针具有不同的大小时,我才会问这个(第二个问题)。

c++ pointers void-pointers language-lawyer pointer-conversion

56
推荐指数
5
解决办法
8669
查看次数

“this”参数是在其他成员函数参数之前还是之后求值?

在下面的代码中,在set()a 上调​​用一个成员函数model,它是一个空指针。这将是未定义的行为。然而,成员函数的参数是另一个函数调用的结果,该函数调用检查是否为model空指针并在这种情况下抛出异常。是否保证estimate()总是在访问之前被调用model,还是仍然是未定义行为(UB)?

#include <iostream>
#include <memory>
#include <vector>


struct Model
{
    void set(int x)
    {
        v.resize(x);
    }

    std::vector<double> v;
};


int estimate(std::shared_ptr<Model> m)
{
    return m ? 3 : throw std::runtime_error("Model is not set");
}

int main()
{
    try
    {
        std::shared_ptr<Model> model; // null pointer here
        model->set(estimate(model));
    }
    catch (const std::runtime_error& e)
    {
        std::cout << e.what();
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ struct sequence-points language-lawyer

33
推荐指数
3
解决办法
2252
查看次数

为什么我不能用左值初始化这个 std::vector ?

我遇到了一个有趣的问题,我无法理解发生了什么:

/* I WANT 6 ELEMENTS */
int lvalue = 6;

std::vector<int*> myvector { 6 }; /* WORKS FINE */
std::vector<int*> myvector{ lvalue }; /* DOESN'T WORK */
/* Element '1': conversion from 'int' to 'const unsigned __int64 requires a narrowing conversion */
Run Code Online (Sandbox Code Playgroud)

据我所知,我提供的单个整数参数可以解释为使用 argument 调用构造函数size_type count,也可以解释为采用初始值设定项列表的构造函数。似乎initialiser_list只有当我提供左值时才调用构造函数,而size_t count当我给出右值int(好吧,至少是一个文字)时才调用构造函数。为什么是这样?

这也意味着:

int num_elements = 6;
std::vector<int> myvector{num_elements};
Run Code Online (Sandbox Code Playgroud)

结果仅是大小为 的向量1

std::vector<int> myvector(num_elements);
Run Code Online (Sandbox Code Playgroud)

结果是一个 size 的向量num_elements,但我认为应该避免这种初始化,因为偶尔会遇到最令人烦恼的解析问题。

c++ language-lawyer narrowing

26
推荐指数
1
解决办法
1703
查看次数

是 int &amp;ref = ref; 结构良好

我了解到评估未初始化的变量是未定义的行为。特别int i = i;是未定义的行为。我已阅读未初始化变量用作其自身初始化程序的行为是什么?

但是,使用引用变量来初始化自身也是未定义的行为吗?特别是,int &ref = ref;根据 C++ 标准,UB 也是吗?

int &ref = ref; // Is this well-formed or ill-formed or UB
Run Code Online (Sandbox Code Playgroud)

所有编译器都会编译上述程序(clang 会发出警告)。这是因为它是未定义的行为,所以任何事情都可以发生,还是程序格式良好?


此外,如果我为 分配一些值ref,程序的行为会与之前的情况相比发生变化吗?

int &ref = ref;

int main()
{
    ref = 1; //does this change the behavior of the program from previous case
}
Run Code Online (Sandbox Code Playgroud)

我注意到对于第二个片段,我们遇到了段错误。

我读过的一些参考文献是:

用作自己的初始值设定项的未初始化变量的行为是什么?

为什么新变量的初始化本身有效?

c++ reference language-lawyer selfinitialization

22
推荐指数
1
解决办法
1172
查看次数

由于整数是内置类型,因此整数类类型在 C++ 中意味着什么

在阅读文档时,std::numeric_limits我发现了以下声明

还提供了所有整数类类型的特化。(自 C++20 起)

我的问题是上面的语句中整数类类型是什么意思。我的意思是,我知道这int是 C++ 中的内置类型。我们可以在C++中提供用户定义的类。但我从未读过有关整数类类型的内容。我尝试在谷歌上搜索该短语,但没有找到与此相关的任何内容。

c++ types c++20

21
推荐指数
2
解决办法
1901
查看次数

最令人烦恼的解析是一个正式定义的概念吗

我正在阅读一篇 SO 帖子,其中一位用户发表了以下评论

另请注意,ArrTest<int> ar();使用了最令人烦恼的 parse

但另一位用户却表示相反:

ArrTest<int> ar();不是“最令人烦恼的解析”。这只是一个函数声明。对于初学者来说这当然很麻烦,但是,正如您链接到的页面所示,“最令人烦恼的解析”更加复杂。

下面给出了该帖子中的代码示例以供参考:

template <class ItemType>
class ArrTest {
public:
    ArrTest();
private:
    ItemType* info;
};
//some other code here

int main() {
    ArrTest<int> ar();  //DOES THIS USE THE MOST VEXING PARSE?
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的第一个问题是 C++ 标准正式定义的“最令人烦恼的解析”的概念。我的第二个问题是该语句是否ArrTest<int> ar();使用了最令人烦恼的解析。也就是说,上面引用的两条评论哪一条在技术上是正确的?


似乎也表明这MyObject object();是最令人烦恼的解析。

c++ most-vexing-parse language-lawyer

19
推荐指数
1
解决办法
1068
查看次数

可变参数模板在 gcc 中有效,但在 clang 中无效

我正在使用此处列出的书籍学习 C++ 。我特别读到了有关可变参数模板的内容。现在,为了进一步阐明我的概念,我还编写了简单的示例,并尝试使用调试器和 cout 语句自己理解它们。

下面给出了一个用 gcc 编译但被 clang 拒绝的程序。演示

template<typename T, typename... V> 
struct C 
{
    T v(V()...);;
};
int main()
{
    
    C<int> c; //works with gcc but rejected in clang 
    C<int, double, int, int> c2; //same here: works with gcc but rejected in clang
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是哪个编译器就在这里(如果有的话)?

这是 clang 给出的错误:

<source>:6:12: error: '...' must be innermost component of anonymous pack declaration
    T v(V()...);;
           ^~~
          ...
1 error generated.
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-templates

15
推荐指数
2
解决办法
750
查看次数

为什么类可以轻松复制所有私有特殊成员函数?

代码如下:

#include <iostream>
#include <type_traits>

class A
{
    A() = default;
    A(const A&) = default;
    A(A&&) = default;
    A& operator=(const A&) = default;
    A& operator=(A&&) = default;
    ~A() = default;
    int a;
};

int main()
{
    std::cout << std::boolalpha <<
        std::is_trivially_copy_assignable_v<A> << " " <<
        std::is_trivially_copy_constructible_v<A> << " " <<
        std::is_trivially_move_assignable_v<A> << " " <<
        std::is_trivially_move_constructible_v<A> << " " <<
        std::is_trivially_destructible_v<A> << " " <<
        std::is_trivially_copyable_v<A> << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

And the output is false false false false false …

c++ language-lawyer c++20 trivially-copyable

14
推荐指数
2
解决办法
1357
查看次数

为什么我在此处收到“子项具有其类型使用匿名命名空间的基数”警告

我试图理解为什么在尝试编译此代码时收到警告 -Wsubobject-linkage:

\n

基本.hh

\n
#pragma once\n\n#include <iostream>\n\ntemplate<char const *s>\nclass Base\n{\npublic:\n  void print()\n  {\n    std::cout << s << std::endl;\n  }\n};\n
Run Code Online (Sandbox Code Playgroud)\n

孩子.hh

\n
#pragma once\n\n#include "base.hh"\n\nconstexpr char const hello[] = "Hello world!";\n\nclass Child : public Base<hello>\n{\n};\n
Run Code Online (Sandbox Code Playgroud)\n

主程序.cc

\n
#include "child.hh"\n\nint main(void)\n{\n  Child c;\n  c.print();\n  return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

跑步时g++ main.cc I get this warning:

\n
In file included from main.cc:1:\nchild.hh:7:7: warning: \xe2\x80\x98Child\xe2\x80\x99 has a base \xe2\x80\x98Base<(& hello)>\xe2\x80\x99 whose type uses the anonymous namespace [-Wsubobject-linkage]\n    7 | class Child : …
Run Code Online (Sandbox Code Playgroud)

c++ gcc

12
推荐指数
2
解决办法
1187
查看次数