聚合 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 只是一个 属性 声明。
我们知道,在 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 只是一个 属性 声明。