相关疑难解决方法(0)

我真的需要为const对象实现用户提供的构造函数吗?

我有代码:

class A {
  public:
    A() = default;

  private:
    int i = 1;
};

int main() {
  const A a;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

它在g ++上编译很好(参见ideone),但在clang ++上失败并出现错误:

const类型'const A'的对象的默认初始化需要用户提供的默认构造函数

我在LLVM错误跟踪器上报告了这个问题,并使其无效.

我认为试图说服铿锵的开发者绝对毫无意义.另一方面,我没有看到这种限制的原因.


任何人都可以建议,如果C++ 11标准以某种方式暗示此代码无效?或者我应该向g ++报告错误?或许在语言规则方面有足够的自由来以多种方式处理这些代码?

c++ constructor const language-lawyer c++11

42
推荐指数
2
解决办法
2858
查看次数

什么是c ++中对象的动态初始化?

什么是c ++中对象的动态初始化?

请用一个简单的例子来解释......

c++ initialization dynamic object

36
推荐指数
2
解决办法
5万
查看次数

const T {}; 作品,const T; 当T是非POD时失败,

首先,我有一个结构,其中一个值具有默认值

struct S {
    int a = 1;
};
Run Code Online (Sandbox Code Playgroud)

当gcc和clang都是非const/non-constexpr时,可以默认构造此类型.在两者之下,std::is_pod<S>::valuefalse.奇怪的行为如下:

S s1; // works under both
const S s2{}; // works under both
const S s3; // only works in gcc, clang wants a user-provided constructor
Run Code Online (Sandbox Code Playgroud)

以下尝试都没有对clang产生影响:

struct S {
    int a = 1;
    constexpr S() = default; // defaulted ctor
    virtual void f() { } // virtual function, not an aggregate
  private:
    int b = 2; // private member, really not an aggregate
};
Run Code Online (Sandbox Code Playgroud)

我唯一可以做的就是 …

c++ gcc clang language-lawyer c++14

24
推荐指数
2
解决办法
601
查看次数

未初始化的常量

这与当前的MSVC编译器完美编译:

struct Foo
{
} const foo;
Run Code Online (Sandbox Code Playgroud)

但是,它无法使用当前的g ++编译器进行编译:

error: uninitialized const 'foo' [-fpermissive]
note: 'const struct Foo' has no user-provided default constructor
Run Code Online (Sandbox Code Playgroud)

如果我自己提供默认构造函数,它可以工作:

struct Foo
{
    Foo() {}
} const foo;
Run Code Online (Sandbox Code Playgroud)

这是MSVC的另一个案例是过于宽松,还是g ++过于严格?

c++ const g++ default-constructor visual-c++

16
推荐指数
2
解决办法
1万
查看次数

用户声明的默认构造函数+类内初始值设定项!=用户提供的构造函数?

锵文档整齐地解释说,

如果类或结构没有用户定义的默认构造函数,C++不允许您默认构造它的const实例([dcl.init],p9)

基本原理是如果const对象未正确初始化,则以后不能更改.以下代码仅具有用户声明的默认构造函数Test,但其所有成员都具有类内初始值设定项,

#include<iostream>

class Test
{
public:
    Test() = default;
    void print() const { std::cout << i << "\n"; }
private:
    int i = 42;   // will propagate to the default constructor!
};

int main()
{
    Test const t; // <-- Clang chokes on the const keyword, g++ does not
    t.print();    // prints 42
}
Run Code Online (Sandbox Code Playgroud)

所以用户提供默认构造函数的基本原理对我来说似乎是多余的.事实上,g ++ 4.8.1确实可以毫无问题地编译它(在线示例),尽管Clang <= 3.2没有.

问题:为什么完整的类内initalizers +用户声明的默认构造函数的组合不足以默认构造一个const对象?是否有针对C++ 14标准的修复程序?

更新:任何人都可以尝试使用Clang 3.3/3.4,看看与Clang …

c++ default-constructor in-class-initialization c++11 c++14

13
推荐指数
1
解决办法
594
查看次数

constexpr标准仿函数的正确用法是什么?

请使用以下代码:

#include <iostream>
#include <functional>

template <template<typename> class Op>
auto applyOp(const uint8_t lhs, const uint8_t rhs) {
    constexpr Op<uint8_t> op;

    return op(lhs, rhs);
}

int main() {
    std::cout << +applyOp<std::bit_and>(19, 180) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

使用时g++,这个编译并运行得很好.但是会clang++产生错误:

test.cpp:5:27: error: default initialization of an object of const type 'const bit_and<uint8_t>' (aka 'const bit_and<unsigned char>') without a user-provided default constructor
    constexpr Op<uint8_t> op;
                          ^
                            {}
test.cpp:11:19: note: in instantiation of function template specialization 'applyOp<std::bit_and>' requested here
    std::cout << +applyOp<std::bit_and>(19, 180) …
Run Code Online (Sandbox Code Playgroud)

c++ templates language-lawyer constexpr c++14

12
推荐指数
1
解决办法
504
查看次数

下面显示的片段在Coliru和Ideone中编译,但根据iso§8.5p6它不应该,或者我错过了什么?

从C++ 11标准§8.5p6我们得到:

如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型.

下面的代码应该不会编译.但它确实在Coliru和Ideone都有.

class A{};

int main() {
    const A a;
}
Run Code Online (Sandbox Code Playgroud)

编辑:

在尝试理解这里发生了什么时,我最终得到了以下代码,它编译(至少它符合标准,与A用户提供的构造函数一样).但后来出现了以下问题:哪个标准子句确保a.b.j用0初始化(参见Ideone中的代码),下面是什么?

#include <iostream>
struct B { int j; B(){ std::cout << "B()" << '\n'; } };
struct A
{
    struct B b;
    int i;

    public:
    A(): i(1) { std::cout << "A()" << '\n'; }

};  

int main() {
    const A a;
    std::cout << a.b.j << '\n';
    std::cout << a.i << '\n';
}
Run Code Online (Sandbox Code Playgroud)

EDIT1:

很抱歉上面的编辑,但我还没有使用Unix.上周, …

c++ default-constructor language-lawyer c++11

9
推荐指数
1
解决办法
300
查看次数

在 C++ 中声明一个 const 对象需要一个用户定义的默认构造函数。如果我有一个可变成员变量,为什么不呢?

在 C++ 中,要声明具有成员变量 as 的类的对象const,我们必须有一个用户定义的默认构造函数。下面的代码说明了这一点。

class Some {
    int value;
};

int main() {
    // error: default initialization of an object of const type 'const Some'
    //        without a user-provided default constructor
    const Some some;

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

但是,如果类拥有的成员变量被限定为可变的,编译器将不会报告任何错误。作为参考,我使用命令编译clang++ -std=c++17 -stdlib=libc++ helloworld.cpp -o helloworld.out --debug。我想知道这个结果是由于编译器中的错误还是根据C++语言中定义的语法。

class Some {
    mutable int value;
};

int main() {
    const Some some;

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

c++ clang++

8
推荐指数
1
解决办法
640
查看次数

clang和g ++在处理const对象时的差异

考虑一下代码:

struct Foo
{
    int x = 10;
};

int main()
{
    const Foo foo;
}
Run Code Online (Sandbox Code Playgroud)

它在g ++ http://coliru.stacked-crooked.com/a/99bd8006e10b47ef下汇编,但在clang ++ http://coliru.stacked-crooked.com/a/93f94f7d9625b579下吐出错误:

error: default initialization of an object of const type
      'const Foo' requires a user-provided default constructor
Run Code Online (Sandbox Code Playgroud)

我不确定谁在这里.为什么我们需要一个默认的ctor,因为我们执行了类内初始化?

c++ const c++11

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

何时以及如何默认初始化const变量?

clang++没有用户定义的构造函数,它不允许默认初始化类型的const变量 ; g++限制性稍差(见下文).根据这个答案,这是因为POD类型"默认情况下没有初始化".如果我理解正确,这意味着默认初始化不会调用默认构造函数,也不会调用值初始化,因此POD类型中的数据成员不会被初始化.当然,使用带有未初始化值的const POD类型是没有意义的,因为它们永远不会被初始化,因此使用起来不安全.

这种情况有一些变种:

  1. 该类型在技术上是"POD",但不包含数据成员(仅限函数).(clang++并不认为这是一种特殊情况,我认为也不是标准的,但g++也允许它,即使构造函数被标记explicit.)
  2. 使用定义空构造函数{}.(这是clang描述问题的页面上的推荐解决方法.)
  3. 声明了默认构造函数=default.(C++ 11以后;类型仍然被认为是POD,因此编译器和标准都不会将其视为特殊情况.)
  4. 使用显式调用聚合初始化{},(如果我理解正确)变为值初始化.(C++ 11以后;两个编译器 - 我认为,标准 - 允许这个.)

在第一种情况下,可能没有未初始化的成员,因此不清楚为什么任何类本身的实例化都将被视为"未初始化",而不管它是否是const.既然g++允许这种行为,使用安全吗?为什么禁止clang++和标准?(还有其他任何情况g++允许POD默认初始化哪里clang++没有?)

在第二和第三种情况下,使用{}代替的要求=default对我来说似乎很奇怪.编辑: 这个问题很好地解释了差异,所以我已经删除了询问区别的部分问题.(尽管如此,我仍然认为这是一种非常令人困惑的语言方面.)

最后,将Foo f{}始终是零初始化内置类型的成员如果Foo::Foo(void){},=default或隐式声明的?

c++ constructor default-constructor c++11

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

默认构造函数与隐式构造函数

可能有人已经问过这个问题,但在谷歌上搜索“默认”、“默认”、“明确”等并没有给出好的结果。但无论如何。

我已经知道显式定义的默认构造函数(即没有参数)和显式定义的默认构造函数(即带有关键字default)之间存在一些差异,从这里开始:C++11 中的新关键字 =default

但是显式定义的默认构造函数和隐式定义的构造函数(即当用户根本不编写它时)之间有什么区别?

class A
{
public:
    A() = default;
    // other stuff
};
Run Code Online (Sandbox Code Playgroud)

对比

class A
{
    // other stuff
};
Run Code Online (Sandbox Code Playgroud)

想到的一件事是,当存在非默认构造函数时,用户还必须明确定义默认构造函数。但是还有其他区别吗?

编辑:我最感兴趣的是知道是否有任何充分的理由来编写A() = default;而不是完全省略构造函数(当然,假设它是该类唯一明确定义的构造函数)。

c++ constructor default-constructor

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

C++:由隐式构造函数初始化int变量

我正在学习C++,我对int变量的初始化感到有点困惑.

这段代码(包括注释)是Nawaz在本主题中的答案的复制/粘贴为什么C++需要用户提供的默认构造函数来默认构造一个const对象?

struct POD
{
  int i;
};

POD p1; //uninitialized - but don't worry we can assign some value later on!
p1.i = 10; //assign some value later on!

POD p2 = POD(); //initialized
Run Code Online (Sandbox Code Playgroud)

对于p2,我了解到以下情况:

  • 调用默认构造函数POD()以创建临时POD对象.构造函数不是用户定义的,因此它是隐式的.对于像int这样的内置类型,隐式默认构造函数不执行任何操作(不进行初始化).因此包含一些随机的东西.
  • 调用复制构造函数以使用临时POD对象(其i仍未初始化)创建p2 .因此,不应该初始化p2的i成员.

但是,评论说p2已初始化!欢迎任何解释.谢谢.

c++ int constructor

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

Clang Compile错误,默认初始化

考虑以下示例:

#include <iostream>
#include <type_traits>

struct A
{
  //A() = default; // does neither compile with, nor without this line
  //A(){};         // does compile with this line
  int someVal{ 123 };


  void foobar( int )
  {
  };
};


int main()
{
    const A a;
    std::cout << "isPOD = " << std::is_pod<A>::value << std::endl;
    std::cout << "a.someVal = " <<a.someVal << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

查看实例

这可以用g ++编译,但不能用clang ++编译,尝试使用以下命令: clang++ -std=c++11 -O0 main.cpp && ./a.out

从clang编译错误:

main.cpp:19:13:错误:const类型'const A'对象的默认初始化需要用户提供的默认构造函数

我从这个Stack Overflow问题中了解到,非POD类获得默认构造函数.这甚至不是必需的,因为变量具有c ++ …

c++ c++11 clang++

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