概念不适用于内联类定义

问题描述 投票:0回答:1

我很难理解为什么下面的代码不满足这个概念:

#include <concepts>

template <class T> concept has_Default_Constructor = requires (T t)
{
 { T () } -> std::same_as <T>;
};

class A
{
public:
  class B
  {
  public:
    int x = 0;
  };

  static_assert (has_Default_Constructor <B>); // asserts in gcc and clang

  B b;
};

这可以在 MSVC 中编译,但不能在 gcc 或 clang 中编译。 (截至 2024 年 2 月 3 日的所有最新版本)

如果我将 static_assert 移到 A 类之外,它就可以正常工作:

class A
{
public:
  class B
  {
  public:
    int x = 0;
  };

  B b;
  //static_assert (has_Default_Constructor <B>);
};

static_assert (has_Default_Constructor <A::B>); // does not assert

(我无法在实际代码中执行此操作,因为在 A 中的成员构造中使用了 has_Default_Constructor。)

我假设问题与不完整(未调整大小)的类有关,但我不明白它在这种情况下如何应用。

c++ nested c++20 c++-concepts
1个回答
0
投票

默认成员初始值设定项位于完整类上下文中,并且隐式声明的默认构造函数的

noexcept
规范取决于默认成员初始值设定项是否可能抛出。

嵌套类的完整类上下文还包括包含类的定义。所以编译器一般只能在

B
定义的右大括号之后完成
A
默认构造函数的声明。

我不确定该标准是否正确指定了直接使用概念的特定情况下的行为。但是,在封闭类定义中的嵌套类上使用类型特征时,通常会遇到此类问题。类型特征的实例化点将在命名空间范围声明之前,即封闭类定义,其中嵌套类还不能完成。

© www.soinside.com 2019 - 2024. All rights reserved.