我正在编写一个具有显式构造函数的类,该类采用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");
}
答案 0 :(得分:4)
嗯,你的构造函数是显式的,所以你需要使用它:
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)的约束,请参阅此答案Restrict variadic template arguments。或者,根据您的需要,取消支票也是一种选择。
答案 1 :(得分:1)
到目前为止,我提出的最好的是:
std::vector<Symbol> symbols;
for(auto v: { "a", "b", "c"})
symbols.emplace_back(v);