小编Sto*_*ica的帖子

char s []和char*s有什么区别?

在C中,可以在声明中使用字符串文字,如下所示:

char s[] = "hello";
Run Code Online (Sandbox Code Playgroud)

或者像这样:

char *s = "hello";
Run Code Online (Sandbox Code Playgroud)

那么区别是什么呢?我想知道在编译和运行时的存储持续时间实际发生了什么.

c string constants char

495
推荐指数
6
解决办法
33万
查看次数

由于类之间的循环依赖性而解决构建错误

我经常发现自己处于一种情况,我在C++项目中面临多个编译/链接器错误,因为一些糟糕的设计决策(由其他人做出:))导致不同头文件中C++类之间的循环依赖(也可能发生)在同一个文件中).但幸运的是(?)这种情况经常不足以让我在下次再次发生问题时记住这个问题的解决方案.

因此,为了便于将来回忆,我将发布一个代表性问题和解决方案.更好的解决方案当然是受欢迎的.


  • A.h

    class B;
    class A
    {
        int _val;
        B *_b;
    public:
    
        A(int val)
            :_val(val)
        {
        }
    
        void SetB(B *b)
        {
            _b = b;
            _b->Print(); // COMPILER ERROR: C2027: use of undefined type 'B'
        }
    
        void Print()
        {
            cout<<"Type:A val="<<_val<<endl;
        }
    };
    
    Run Code Online (Sandbox Code Playgroud)

  • B.h

    #include "A.h"
    class B
    {
        double _val;
        A* _a;
    public:
    
        B(double val)
            :_val(val)
        {
        }
    
        void SetA(A *a)
        {
            _a = a;
            _a->Print();
        }
    
        void Print()
        {
            cout<<"Type:B val="<<_val<<endl;
        }
    };
    
    Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors circular-dependency c++-faq

334
推荐指数
7
解决办法
18万
查看次数

类静态变量初始化顺序

我有一个A类,它有两个静态变量.我想用另一个不相关的静态变量初始化一个,就像这样:

#include <iostream>
class A
{
public:
    static int a;
    static int b;
};

int A::a = 200;
int a = 100;
int A::b = a;
int main(int argc, char* argv[])
{
    std::cout << A::b << std::endl;

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

输出是200.所以,谁能告诉我为什么?

c++ scope language-lawyer

61
推荐指数
4
解决办法
2354
查看次数

为什么 16 位和 32 位整数的有符号加法和无符号加法的转换方式不同?

看来 GCC 和 Clang 对有符号整数和无符号整数之间的加法的解释不同,具体取决于它们的大小。为什么会这样?所有编译器和平台上的转换是否一致?

举个例子:

#include <cstdint>
#include <iostream>

int main()
{

    std::cout <<"16 bit uint 2 - int 3 = "<<uint16_t(2)+int16_t(-3)<<std::endl;
    std::cout <<"32 bit uint 2 - int 3 = "<<uint32_t(2)+int32_t(-3)<<std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果:

$ ./out.exe   
16 bit uint 2 - int 3 = -1
32 bit uint 2 - int 3 = 4294967295
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我们都得到 -1,但其中一个被解释为无符号整数并下溢。我本以为两者都会以相同的方式进行转换。

那么,为什么编译器对它们的转换如此不同,这能保证一致吗?我用 g++ 11.1.0、clang 12.0 对此进行了测试。以及 Arch Linux 和 Debian 上的 g++ 11.2.0,得到相同的结果。

c++ language-lawyer implicit-conversion

43
推荐指数
3
解决办法
3891
查看次数

无论指针类型如何,都必须将“throw nullptr”捕获为指针吗?

以下程序抛出nullptr异常,然后捕获异常int*

#include <iostream>

int main() {
    try {
        throw nullptr;
    }
    catch(int*) {
        std::cout << "caught int*";
    }
    catch(...) {
        std::cout << "caught other";
    }
}
Run Code Online (Sandbox Code Playgroud)

在 Clang 和 GCC 中,程序成功打印caught int*, demo: https://gcc.godbolt.org/z/789639qbb

但是在 Visual Studio 16.11.2 中,程序打印caught other. 这是 MSVC 中的错误吗?

c++ exception language-lawyer

41
推荐指数
1
解决办法
1425
查看次数

删除版权副本和版权转让-是公共的,私人的还是受保护的?

为了使对象不可复制,我们可以显式删除其复制构造函数和复制分配运算符。

我的问题是:什么是做正确的地方-在publicprivateprotected之类的部分?并且-这种选择有什么区别吗?

c++ access-modifiers deleted-functions c++11

32
推荐指数
4
解决办法
1919
查看次数

标准为何不将模板构造函数视为副本构造函数?

这是复制构造函数[class.copy.ctor / 1]的定义

如果类X的非模板构造函数的第一个参数为X&,const X&,volatile X&或const volatile X&类型,并且没有其他参数,或者所有其他参数都具有默认参数([dcl。 fct.default])。

为什么标准将模板排除为复制构造函数?

在这个简单的示例中,两个构造函数都是副本构造函数:

struct Foo {
    Foo(const Foo &); // copy constructor
    Foo(Foo &);       // copy constructor
};
Run Code Online (Sandbox Code Playgroud)

参见以下类似示例:

struct Foo {
     Foo() = default;

     template <typename T>
     Foo(T &) {
         printf("here\n");
     }
};

int main() {
    Foo a;
    Foo b = a;
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,here将被打印。因此,似乎我的模板构造函数是一个复制构造函数,至少它的行为类似于一个(在通常调用复制构造函数的上下文中被调用)。

为什么文本中存在“非模板”要求?

c++ templates constructor copy-constructor language-lawyer

32
推荐指数
2
解决办法
1757
查看次数

为什么没有if constexpr使这个核心常量表达式错误消失?

参考这个问题.用于初始化constexpr变量的核心常量表达式是错误的y.这么多是给定的.

但如果我试着if变成if constexpr:

template <typename T>
void foo() {
    constexpr int x = -1;
    if constexpr (x >= 0){
        constexpr int y = 1 << x;
    }
}

int main(){
    foo<int>();
}
Run Code Online (Sandbox Code Playgroud)

错误仍然存​​在.GCC 7.2仍然给出:

error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

但我认为语义检查应该在废弃的分支上保持不成形.

constexpr但是,通过lambda 进行间接确实有帮助:

template <typename T>
void foo(){
    constexpr int x = -1;
    constexpr auto p = []() constexpr { return x; }; …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constexpr c++17 if-constexpr

31
推荐指数
3
解决办法
1475
查看次数

不完整类型上的std :: is_constructible

我有以下代码:

#include <iostream>

class A;

int main()
{
    std::cout << std::is_constructible<A>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

当我使用GCC 8.3时,此代码会编译。但是,当我使用Clang 8.0时,出现编译错误,即不能在类型特征中使用不完整的类型。

哪一个是正确的?是否允许我使用is_constructible不完整的类型(预期值为false),还是不允许我使用?

c++ language-lawyer c++11

30
推荐指数
3
解决办法
1088
查看次数

为什么在C ++ 20中删除了std :: type_info :: operator!=?

根据cppreferencestd::type_info::operator!=被C ++ 20删除,但是std::type_info::operator==显然仍然存在。

背后的原因是什么?我可能会同意比较不平等是没有意义的,但是然后比较相等也同样是没有意义的,不是吗?

相比之下,必须编写if(!(id1 == id2))并不会使任何代码更清晰if(id1 != id2),相反,相反……

c++ c++20

28
推荐指数
2
解决办法
444
查看次数