I want to pass variable number of references to objects to a C++ function. Say, I have class ParameterBase
and instances of classes derived from this base class. I want a function, which checks that all parameters are specified.
//Abstract base class
class ParameterBase
{
public:
std::string name();
bool specified();
};
class ParameterInt : public ParameterBase
{
//whatever
};
class ParameterString : public ParameterBase
{
//whatever
};
/// Check that all parameters in the list are specified and
/// print the name of the first unspecified parameter.
bool all_specified(const magic_container<ParameterBase&>& parameters)
{
for(const auto& par : parameters)
{
if (!par.specified())
{
std::cerr << "Parameter '" << par.name() << "' was not specified\n";
return false;
}
}
return true;
}
int main()
{
ParameterInt n1, n2, n3;
ParameterString s1, s2, s3;
if (all_specified({n1, n2, s1, n3, s2, s3}))
{
std::cout << "Joy and happiness\n";
} else
{
std::cout << "Disaster\n";
}
return 0;
}
I understand, I can work around this problem using container of pointers or reference wrappers to objects, but may be I use wrong approach altogether? All I want is to be able to
{n1, n2, s1, n3, s2, s3}
of variable size,
all elements have common ancestor;What is the simplest and most elegant way of doing this?
I would go with reference_wrapper or pointer container.
but as alternative, you might use varaidic template:
template <typename... Ts>
bool all_specified(const Ts& parameters)
{
return ([&](){
if (!parameters.specified()) {
std::cerr << "Parameter '" << parameters.name() << "' was not specified\n";
return false;
} else {
return true;
}
}() && ...);
}
And call would be similar to:
if (all_specified(n1, n2, s1, n3, s2, s3))