Home > other >  Invalid parameter type ‘void’ even when testing for 'void'
Invalid parameter type ‘void’ even when testing for 'void'

Time:05-26

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 conditional_t and is_same_v.

I cannot see what is incorrect, can someone please tell me?

CodePudding user response:

Not really an answer to your question (Why doesn't my code work), but this works:

template<typename ArgType, typename ReturnType>
struct Test
{
  using FunctionPointerType = ReturnType(*)(ArgType);
  FunctionPointerType Func;
};

template<typename ReturnType>
struct Test<void, ReturnType>
{
  using FunctionPointerType = ReturnType(*)();
  FunctionPointerType Func;
};

CodePudding user response:

template<typename ArgType, typename ReturnType>
struct Test
{
  using FunctionPointerType = std::conditional_t<std::is_same_v<ArgType, void>, ReturnType(*)(), ReturnType(*)(ArgType)>;
  FunctionPointerType Func;
};

conditional_t takes 3 arguments. A bool and 2 types.

The right type, when ArgType is void, is ReturnType(*)(void) -- not a legal type.

The error happens immediately.

MSVC has a bad habit of treating templates like macros.

Something like this:

template<class...Args>
struct Apply {
  template<template<class...>class Z>
  using To = Z<Args...>;
};

template<class R, class...Args>
using FunctionPtr = R(*)(Args...);

template<typename ArgType, typename ReturnType>
struct Test
{
  using FunctionPointerType =
    std::conditional_t<
      std::is_same_v<ArgType, void>,
      Apply<ReturnType>,
      Apply<ReturnType, ArgType>
    >::template To<FunctionPtr>;
  FunctionPointerType Func;
};

builds 2 pack appliers, then applies one to FunctionPtr depending on which one is picked.

Here, I avoid forming X(void) types until after the condition branch has occurred.

  • Related