The following compiles on Visual Studio:
template<typename ArgType, typename ReturnType>
struct Test
{
using FunctionPointerType = std::conditional_t<
std::is_same_v<ArgType, void>
, ReturnType(*)()
, ReturnType(*)(ArgType)
>;
FunctionPointerType Func;
};
int main()
{
Test<void, char> tt;
}
But does not compile on Linux g++. The error I get is
error : invalid parameter type ‘void’
I know I cannot use void in templates, which is why I have used std::conditional_t
and std::is_same_v
.
I cannot see what is incorrect, can someone please tell me?
In std::conditional_t<B, T, F>
both the true
and false
specialization should have valid types T
as well as F
. In your case, since the F
deduce to an invalid char(*)(void)
type, std::conditional
can not be used here.
I would suggest a helper traits function_ptr_t
as alternative
#include <type_traits>
template<typename RetType, typename... Args> struct function_ptr final {
using type = RetType(*)(Args...);
};
template <typename RetType> struct function_ptr<RetType, void> final {
using type = RetType(*)();
};
// alias helper
template<typename RetType, typename... Args>
using function_ptr_t = typename function_ptr<RetType, Args...>::type;
template<typename RetType, typename... Args>
struct Test
{
function_ptr_t<RetType, Args...> Func;
};
Note that, I have swapped the template arguments in the class template Test
, and made the second template argument be a variadic, so that the Test<char>
will result in a member function pointer of type char(*)()
.
That means the following will work:
Test<char> tt1;
static_assert(std::is_same_v<char(*)(), decltype(tt1.Func)>, " are not same!");
Test<char, void> tt2;
static_assert(std::is_same_v<char(*)(), decltype(tt2.Func)>, " are not same!");
Test<void, double> tt3;
static_assert(std::is_same_v<void(*)(double), decltype(tt3.Func)>, " are not same!");
If that is not, you wanted, substitute the variadic template arguments to be a normal one.