我们知道,在c++ 20中,具有用户声明的构造函数的类不是聚合的。
现在,考虑以下代码:#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都不编译这段代码。因此,尽管这里没有实例化的构造函数,但类不是聚合。
构造函数模板是否被认为是"声明的构造函数"?《标准报》对这种情况怎么说?
聚合的定义已经改变了很多,但这里的相关部分一直相当稳定。[dcl.init.]aggr]说:
聚合是具有
的数组或类([class])。
- 没有用户声明或继承的构造函数([class. tor]),
- 没有私有或受保护的直接非静态数据成员([class.access]),
- 没有虚函数([class.virtual]),和
- 没有虚拟、私有或受保护的基类([class.mi])。
注意它只是说没有声明的构造函数,句号。对于类模板的特定专门化,构造函数是否可行,没有什么微妙的问题。完全没有。
那么给定这样的内容:
template <bool B>
struct X {
int i;
X(int i) requires B;
};
X<false>
仍然不是聚合,即使它唯一声明的构造函数不适合该专门化。没关系。聚合性仅是声明的属性。