聚合 class 和不可行的构造函数模板

Aggregate class and non-viable constructor template

我们知道,在 C++20 中,具有用户声明的构造函数的 class 不是聚合。

现在,考虑以下代码:

#include <type_traits>

template <bool EnableCtor>
struct test {
  template <bool Enable = EnableCtor, class = std::enable_if_t<Enable>>
  test() {}
  int a;
};

int main() {
    test<false> t {.a = 0};
}

GCC 和 CLang 均未编译此代码。因此,class 不是聚合,尽管这里没有实例化的构造函数。

构造函数模板是否被视为“声明的构造函数”?标准对这种情况怎么说?

聚合的定义发生了很大变化,但这里的相关部分一直很稳定。 [dcl.init.aggr] 中的 C++20 措辞说:

An aggregate is an array or a class ([class]) with

  • no user-declared or inherited constructors ([class.ctor]),
  • no private or protected direct non-static data members ([class.access]),
  • no virtual functions ([class.virtual]), and
  • no virtual, private, or protected base classes ([class.mi]).

注意它只是说没有声明的构造函数,句号。关于构造函数是否适用于 class 模板的特定专业化,这并不是什么微妙的事情。根本就 none。

所以给出这样的东西:

template <bool B>
struct X {
    int i;
    X(int i) requires B;
};

X<false> 仍然不是聚合,即使它唯一声明的构造函数对于该专业化不可行。没关系。 Aggregate-ness 只是一个 属性 声明。