通过显式构造函数初始化数组

Initializing array through explicit constructor

本文关键字:初始化 数组 构造函数      更新时间:2023-10-16

我正在写一个具有const char*参数的显式构造函数的类。出于这个问题的目的和目的,它看起来像这样:

struct Symbol
{
    Symbol()=default;
    explicit Symbol(const char*);
};

现在,我想编写一个用于文档目的的示例,该示例初始化了一个数组(数组/向量/列表 - 我不在乎确切的类型(,我需要一个示例才能尽可能清楚和简洁。理想情况下,它看起来像这样:

Symbol symbols[] = { "a", "b", "c"};

由于明确的关键字而没有编译,我不准备使构造函数隐含。

如何使这项工作,重点是使示例代码尽可能表达?

编辑:我在卡利斯(Caleth(的一点帮助下去了博洛夫(Bolov(的解决方案:

struct Symbol
{
    Symbol();
    explicit Symbol(const char*);
    template <class... Args> 
    static std::array<Symbol, sizeof...(Args)> Array(Args... args)
    {
        return {Symbol{args}...}; 
    } 
};
int main()
{
    auto symbols = Symbol::Array("a", "b", "c");
}

好吧,您的构造函数是明确的,因此您需要这样使用:

Symbol symbols[] = {Symbol{"a"}, Symbol{"b"}, Symbol{"c"}};

gcc和clang既副本/移动构造函数又是C 17,这是所需的行为,因此没有性能开销。


如果您真的想保留构造函数explicit并能够在不明确说明每个元素的情况下创建一个数组,则可以创建一个辅助函数:

template <class... Args,
          class Enable = std::enable_if_t<(... && std::is_same_v<Args, const char*>)>>
auto make_symbols(Args... args) -> std::array<Symbol, sizeof...(Args)>
{
    return {Symbol{args}...};
}

并这样使用:

auto symbols = make_symbols("a", "b", "c");

再次省略了移动/副本。

make_symbols函数使用C 17功能来检查参数类型。如果您需要对先前标准版本的约束(包括C 11(,请参见此答案限制Variadic模板参数。或者,根据您的需求,删除支票也可以是一种选择。

到目前为止我想出的最好的是:

std::vector<Symbol> symbols;
for(auto v: { "a", "b", "c"})
    symbols.emplace_back(v);