I've effectively got the following problem: I want to be able to build with -Wall -Wextra -Werror
, however, the following code will complain about unused parameters:
struct foo
{
template <typename... Args>
static void bar()
{ }
template <typename T, typename ... Args>
static void bar(T&& value, Args&& ... args)
{
#ifdef DEBUG
std::cout << value;
bar(std::forward<Args>(args)...);
#endif
}
};
The first unused parameter is easy to fix:
#ifdef DEBUG
std::cout << value;
bar(std::forward<Args>(args)...);
#else // Shut the compiler up
(void) value;
#endif
My question is, how can I do this with the remaining args
? Neither
(void)(args...);
Nor
(void)(args)...;
will work, both complain about the parameter pack not being expanded.
(This is under GCC 4.7.3, if that will make any difference to a potential solution).
Parameter packs (C++11) A parameter pack can be a type of parameter for templates. Unlike previous parameters, which can only bind to a single argument, a parameter pack can pack multiple parameters into a single parameter by placing an ellipsis to the left of the parameter name.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.
With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.
Pack expansion A pattern followed by an ellipsis, in which the name of at least one parameter pack appears at least once, is expanded into zero or more comma-separated instantiations of the pattern, where the name of the parameter pack is replaced by each of the elements from the pack, in order. template<class...
When working with variadic template, it is more clean to use sink:
struct sink { template<typename ...Args> sink(Args const & ... ) {} };
#ifdef DEBUG
std::cout << value;
bar(std::forward<Args>(args)...);
#else
sink { value, args ... }; //eat all unused arguments!
#endif
You could really go with conditional naming here.
#ifdef DEBUG
#define DEBUG_NAME(x) x
#else
#define DEBUG_NAME(x)
#endif
static void bar(T&& DEBUG_NAME(value), Args&& DEBUG_NAME(args)) {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With