I'm writing a class that has an explicit constructor taking a const char* argument. For the intents and purposes of this question it looks like this:
struct Symbol
{
Symbol()=default;
explicit Symbol(const char*);
};
Now I want to write an example for documentation purposes that initializes an array (array/vector/list - I don't care about the exact type) and I need the example to be as clear and concise as possible. Ideally it would look like this:
Symbol symbols[] = { "a", "b", "c"};
That does not compile because of the explicit keyword and I am not prepared to make the constructor implicit.
How can I make this work, with the focus of making the example code as expressive as possible?
EDIT: I went for Bolov's solution with a little help from Caleth:
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");
}
Well, your constructor is explicit so you need to use it as such:
Both gcc and clang both the copy/move constructor and since C++17 that is the required behavior so there is no performance overhead.
If you really want to keep the constructor
explicitand be able to create an array without explicitly stating it for every element then you can create a helper function:and use it like this:
Again the move/copies are entirely elided.
The
make_symbolsfunction uses C++17 features for checking the arguments types. If you need the constraint for a previous standard version (including C++11) see this answer Restrict variadic template arguments. Or, depending on your needs, removing the check can also be a choice.