Инициализация массива через явный конструктор

Я пишу класс, который имеет явный конструктор, принимающий const char* аргумент. Для целей и задач этого вопроса это выглядит так:

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

Теперь я хочу написать пример для целей документации, который инициализирует массив (массив / вектор / список — мне наплевать на точный тип), и мне нужно, чтобы пример был как можно более четким и кратким. В идеале это будет выглядеть так:

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

Это не компилируется из-за явного ключевого слова, и я не готов сделать конструктор неявным.

Как я могу сделать эту работу, чтобы сделать пример кода максимально выразительным?

РЕДАКТИРОВАТЬ:
Я пошел на решение Болова с небольшой помощью Калет:

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

Решение

Ну, ваш конструктор явный, поэтому вам нужно использовать его как таковой:

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), посмотрите этот ответ Ограничить аргументы шаблона переменной. Или, в зависимости от ваших потребностей, удаление чека также может быть выбором.

4

Другие решения

Лучшее, что я придумал, это:

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector