gpt4 book ai didi

c++ - Constexpr 类 : Inheritance?

转载 作者:太空狗 更新时间:2023-10-29 20:59:34 29 4
gpt4 key购买 nike

首先,我正在使用 Clang 3.4.1

我正在编写一个全局变量,它必须作为编译时上下文的占位符(主要作为值模板参数)。为此,我编写了一个名为 chameleon 的 constexpr 类(它模仿任何运行时值的行为):

struct chameleon
{
template<typename T>
constexpr operator T() const
{
return T{};
}

constexpr chameleon() = default;
};

由于转换运算符和构造函数都指定为 constexpr,因此我能够在编译时创建该类的实例。 For example :

template<int foo>
struct bar
{};

using mytype = bar<chameleon{}>;

因为这个有效,而且我在其他地方使用它,所以我决定写这样的占位符类型只是继承自 chameleon:

template<std::size_t I>
struct placeholder : public chameleon
{
using chameleon::chameleon;
};

我正在使用 C++11,所以我只使用了"new"(C++11 已经三年了……)继承构造函数功能。

声明占位符变量时:

constexpr const placeholder<0> _1;

编译器拒绝该代码,称它需要用户定义的默认构造函数来进行初始化。所以 “嗯,继承 ctors 不会传播 constexpr 或类似的东西” 是我的想法。然后我将 using 更改为默认的 ctor 声明:

template<std::size_t I>
struct placeholder : public chameleon
{
constexpr placeholder() = default;
};

现在编译器说:

error: default initialization of an object of const type 'const placeholder<0>' requires a user-provided default constructor

如果我将 = default 更改为手动定义的空构造函数 (constexpr placeholder() {}) 那么它可以工作,但构造函数不会被评估为 constexpr 和用法编译时上下文中的 _ 占位符无效(常见的 不是常量表达式 错误)。手动调用 base ctor 也是一样。

我的问题是:继承和constexpr构造函数有什么问题?在编写constexpr类时有什么方法可以使用继承吗?

编辑: 我有一个被零除的错误,使用手动编写的 ctor 的代码工作得很好。另一方面,我不明白为什么继承构造函数或默认构造函数声明都不起作用。问题仍然存在。

最佳答案

So "Well, inheriting ctors doesn't propagate constexpr, or something like that" is what I thought

这不是问题;默认和复制/移动构造函数不能被继承。如果您没有显式定义或默认它们,它们将按照通常的规则隐式定义。

§12.9 [class.inhctor]

3      For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class. ...

5      [ Note: Default and copy/move constructors may be implicitly declared as specified in 12.1 and 12.8. —end note ]

因此,placeholder,无论是否有继承chameleon构造函数的using声明,都会隐式定义一个默认构造函数,这个构造函数为 constexpr.

§12.1/5 [class.ctor]

... If that user-written default constructor would satisfy the requirements of a constexpr constructor (7.1.5), the implicitly-defined default constructor is constexpr. ...

您的类具有用户提供的默认构造函数,满足 §7.1.5/4 中对 constexpr 构造函数的要求。您看到的错误是因为下一部分。


至于为什么必须为const对象提供构造函数定义,让我们看一下您的类。

struct chameleon
{
template<typename T>
constexpr operator T() const
{
return T{};
}

constexpr chameleon() = default;
};

此类既是普通 (9/6) 又是标准布局 (9/7),因此它是 POD (9/10)。 POD 默认情况下是未初始化的,因此没有初始化器的 const POD 将是未初始化的,并且是不可变的,这使得它几乎毫无值(value)(或者我无法想到任何用例,至少) .

通过提供默认构造函数,该类不再是 POD,将被默认初始化。

正如@Casey 在 comments 中指出的那样, 此要求列在 §8.5/7

If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.

关于c++ - Constexpr 类 : Inheritance?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24333458/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com