我有以下示例:
#include <array>
struct A {
const char* str;
const char* str2;
};
template<size_t N>
struct As {
std::array<A,N> elems_;
};
template<class... Args>
As(Args...)->As<sizeof...(Args)>; //<-- NOTE: deduction guide !
constexpr static As as{A{"a","b"}, A{"1","2"}};//<-- 'retyping' A here
int main() {
return as.elems_.size();
}
虽然此代码有效,但我想避免在聚合列表中“重新输入”A
,但如果我将其遗漏,推导指南将失败:“cannot推导出 'As'"
的模板参数(我想这是有道理的)。也许解决这个问题的一种方法是手写我需要的任何数量的推导指南,从那时起我可以在每个推导指南中编写 A
类型(即:我需要的每个尺寸一个推导容器)。
最佳答案
嵌套聚合初始化具有或多或少令人惊讶的行为,您不会添加嵌套 {
/}
匹配。
例如,this是你如何初始化 std::array<std::array<int, 2>, 2>
:
std::array<std::array<int, 2>, 2> arr = { 1, 1, 2, 2 };
正在做 { {1, 1}, {2, 2} }
做 not工作!
同样,在您的情况下聚合初始化不需要嵌套 {
/}
CTAD 已经完成(嗯,给定的模板参数):
constexpr static As<2> as{"a","b", "1","2"}; // Ok!
知道了这一点,我们可以添加以下推导指南:
template<class ... Ts>
As(Ts...) -> As<(sizeof...(Ts) + 1)/2>;
这里选择N
作为“参数数量的一半”。事实上,现在您可以像这样初始化:
constexpr static As as{"a","b", "1","2"}; // Deduces N = 2.
演示:https://godbolt.org/z/oznEwl
是的,这失去了使用 {
构造输入的能力/}
为了更好的可读性,但我在这里归咎于聚合初始化(参见上面的嵌套数组示例)。
关于c++ - 如何避免为聚合初始化重新输入类型信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56236713/