繁体   English   中英

如何避免重新输入聚合初始化的类型信息?

[英]How to avoid retyping type information for aggregate initialization?

我有以下示例:

#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 deduce template arguments for 'As'" (我猜说得通)。 也许解决这个问题的一种方法是手工编写我需要的任何数量的演绎指南,从那以后我可以在每个演绎指南中写出A类型(即:我需要对容器的每个尺寸进行一次演绎)。

嵌套聚合初始化具有或多或少的令人惊讶的行为,您不会添加嵌套的{ / }来匹配。

例如, 是初始化std::array<std::array<int, 2>, 2>

std::array<std::array<int, 2>, 2> arr = { 1, 1, 2, 2 };

否则{ {1, 1}, {2, 2} }没有工作!

类似地,在您的情况下聚合初始化将不需要已经完成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

是的,这会失去使用{ / }来构造输入的能力以获得更好的可读性,但我在这里指责聚合初始化(参见上面的嵌套数组示例)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM