通过显式构造函数初始化数组
Initializing array through explicit constructor
我正在编写一个 class,它有一个带有 const char*
参数的显式构造函数。对于这个问题的意图和目的,它看起来像这样:
struct Symbol
{
Symbol()=default;
explicit Symbol(const char*);
};
现在我想写一个用于初始化数组的示例(array/vector/list - 我不关心确切的类型)并且我需要示例尽可能清晰和简洁。理想情况下它看起来像这样:
Symbol symbols[] = { "a", "b", "c"};
由于 explicit 关键字,无法编译,我不准备隐式构造函数。
我怎样才能完成这项工作,重点是使示例代码尽可能具有表现力?
编辑:
在 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");
}
到目前为止我想到的最好的是:
std::vector<Symbol> symbols;
for(auto v: { "a", "b", "c"})
symbols.emplace_back(v);
好吧,你的构造函数是显式的,所以你需要这样使用它:
Symbol symbols[] = {Symbol{"a"}, Symbol{"b"}, Symbol{"c"}};
gcc 和 clang 都是 copy/move 构造函数,自 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");
再次 move/copies 被完全省略。
make_symbols
函数使用 C++17 功能来检查参数类型。如果您需要以前标准版本(包括 C++11)的约束,请参阅此答案 。或者,根据您的需要,取消检查也是一种选择。
我正在编写一个 class,它有一个带有 const char*
参数的显式构造函数。对于这个问题的意图和目的,它看起来像这样:
struct Symbol
{
Symbol()=default;
explicit Symbol(const char*);
};
现在我想写一个用于初始化数组的示例(array/vector/list - 我不关心确切的类型)并且我需要示例尽可能清晰和简洁。理想情况下它看起来像这样:
Symbol symbols[] = { "a", "b", "c"};
由于 explicit 关键字,无法编译,我不准备隐式构造函数。
我怎样才能完成这项工作,重点是使示例代码尽可能具有表现力?
编辑: 在 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");
}
到目前为止我想到的最好的是:
std::vector<Symbol> symbols;
for(auto v: { "a", "b", "c"})
symbols.emplace_back(v);
好吧,你的构造函数是显式的,所以你需要这样使用它:
Symbol symbols[] = {Symbol{"a"}, Symbol{"b"}, Symbol{"c"}};
gcc 和 clang 都是 copy/move 构造函数,自 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");
再次 move/copies 被完全省略。
make_symbols
函数使用 C++17 功能来检查参数类型。如果您需要以前标准版本(包括 C++11)的约束,请参阅此答案