You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于const-default-constructible对象是否可为非类类型的C++标准条款疑问

Understanding const-default-constructible in C++

First, let's clear up your core misunderstanding: const-default-constructible is not limited to class types—your initial assumption that it only applies to classes, structs, or unions is incorrect. The standard uses this concept for all types, with [dcl.init]/7 spelling out specific rules for class types, while non-class types follow their own constraints for default initialization of const-qualified instances.

Breaking down the definitions

Let’s start with the fundamental meaning:
A type T is const-default-constructible if and only if a const T object can be default-initialized without producing ill-formed code.

For non-class types

For non-class, non-array types (like int, char, or pointers), a const-qualified instance cannot be default-initialized. The standard mandates that such objects must be explicitly initialized. For example:

const int a; // Ill-formed: const non-class objects require explicit initialization

This means non-class types like int are not const-default-constructible, which aligns with your initial intuition about const int.

For class types

[dcl.init]/7 outlines the conditions for a class type T to be const-default-constructible:

  • Either its default initialization invokes a user-provided constructor (not inherited from a base class), OR
  • Every direct non-variant non-static data member has a default member initializer.

These rules ensure a const class instance can be safely default-initialized.

Resolving the "contradiction" in [class.default.ctor]/2

The clause [class.default.ctor]/2 states that a class's defaulted default constructor is deleted if:

Any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-initializer is not const-default-constructible.

This does not conflict with [dcl.init]/7. Here’s why:

  • The word "any" includes non-class types because those types fail the const-default-constructible check (as we saw, const int can’t be default-initialized without an explicit initializer).
  • The clause simply enforces that if you have a const member (class or non-class) without an initializer, that member’s type must support default initialization of its const form—otherwise, the default constructor can’t be valid.

Analyzing your examples

Example 1

struct S {
  const int I; // S::I's type (const int) is NOT const-default-constructible
  S() = default;
};

Since const int is not const-default-constructible and I has no brace-or-equal initializer, the defaulted constructor for S is deleted—this directly follows [class.default.ctor]/2.

Example 2

struct X {
  const int M = 0; // X::M has a default member initializer
  X() = default;
};

Here, the default member initializer (=0) bypasses the need for const int to be const-default-constructible. The default constructor will initialize M using the provided value, so it is well-formed and not deleted. [class.default.ctor]/2 only applies to members without brace-or-equal initializers—this example does not trigger that condition.

Is there a standard wording gap?

No, the wording is consistent once you recognize that const-default-constructible is a general type property, not just a class-specific one. [dcl.init]/7 focuses on class types because their rules are more complex, but the concept applies to all types as needed in other clauses like [class.default.ctor]/2.

内容的提问来源于stack exchange,提问作者mada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:19:07