In bellow sample code I'm trying to check if function arguments are pointers or not with std::is_pointer
it works fine if there is only one parameter, but how to make it work with more parameters, such as in parameter pack?
#include <type_traits>
#include <iostream>
class Test
{
public:
template<typename... Params>
void f(Params... params);
template<typename T, typename... Params>
auto sum(T arg, Params... params)
{
return arg + sum(params...);
}
template<typename T>
auto sum(T arg)
{
return arg;
}
int member = 1;
};
template<typename... Params>
void Test::f(Params... params)
{
// ERROR: too many template arguments for std::is_pointer
if constexpr (std::is_pointer_v<Params...>)
member += sum(*params...);
else
member += sum(params...);
std::cout << member;
}
int main()
{
Test ts;
// both fail
ts.f(1, 2);
ts.f(&ts.member, &ts.member);
// is that even possible?
ts.f(&ts.member, 2);
return 0;
}
I guess if parameters are not either all pointers or all not pointers then we have additional issue, but let's just assume all arguments are either pointers or not.
then what about if arguments are mix of pointers and non pointers anyway?
The problem can be simplified (and the program made to work) by moving the detection of whether a param is a pointer into the variadic template function sum
.
example:
#include <type_traits>
#include <iostream>
class Test
{
public:
template<typename... Params>
void f(Params... params)
{
member += sum(params...);
std::cout << member << '\n';
}
template<typename... Params>
auto sum(Params... params)
{
auto contents = [](auto param)
{
using ParamType = std::decay_t<decltype(param)>;
if constexpr (std::is_pointer_v<ParamType>)
return *param;
else
return param;
};
return (contents(params) + ...);
}
int member = 1;
};
int main()
{
Test ts;
// both fail
ts.f(1, 2);
ts.f(&ts.member, &ts.member);
// is that even possible?
ts.f(&ts.member, 2);
return 0;
}
Expected output:
4
12
26