0

Why is the second version of the class not more specialized than the first? Can't the first version be further specialized with more classes than the second?

Is there an obvious way to make the second class more specialized?

=> Switcher.hpp:122:8: error: partial specialization 'struct SwitchOn<TRslt, TRsltN, (! is_void_v<TRslt>), (! is_void_v<TRsltN>)>' is not more specialized than [-fpermissive]

edit: I expanded the code block with more of its pieces. I tried it out in Godbolt, and got similar errors:


<source>:46:8: error: partial specialization 'struct SwitchOn<TRslt, TRsltN, (! is_void_v<TRslt>), (! is_void_v<TRsltN>)>' is not more specialized than [-fpermissive]
   46 | struct SwitchOn< TRslt, TRsltN, !std::is_void_v<TRslt>, !std::is_void_v<TRsltN> >
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:40:8: note: primary template 'template<class TRslt, class TRsltN, bool TRsltE, bool TRsltNE, class test, class testN> struct SwitchOn'
   40 | struct SwitchOn;
      |        ^~~~~~~~
Compiler returned: 1
#include <type_traits>
#include <functional>

template< typename  TOf, bool TEnabled >
struct BaseVoidl;

template< typename  TOf >
struct BaseVoidl< TOf, true >
{};

template< typename  TOf >
struct BaseVoidl< TOf, false >
{
TOf cProd;

    BaseVoidl<TOf,false>& set( TOf prod )   {
        cProd = prod;
    return *this;
    }

    TOf get()                               {
        return cProd;
    }
};

template< typename  TOf >
struct Voidl
:   public  BaseVoidl< TOf, std::is_void_v<TOf> >
{
};

template<
    typename    TRslt
,   typename    TRsltN
,   bool        TRsltE
,   bool        TRsltNE
,   typename    test    = std::enable_if_t< TRsltE >
,   typename    testN   = std::enable_if_t< TRsltNE >
>
struct SwitchOn;

template<
    typename    TRslt
,   typename    TRsltN
>
struct SwitchOn< TRslt, TRsltN, !std::is_void_v<TRslt>, !std::is_void_v<TRsltN> >
{
    template<
        typename... TArgs
    ,   typename    TFcn    = std::function< TRsltN(TArgs...) >
    >
    static inline void over(
        Voidl<TRslt>    result
    ,   Voidl<TRslt>    resultn
    ,   TFcn            fcn
    ,   TArgs...        args
    ){
        resultn.set( fcn(result.get(),args...) );
    }
};

I am aware that this is a pretty common question, and I have been looking at other people's threads, but I haven't identified a situation that seems the same. Nor have I found a technique I thought I could apply.

For further context, I also want to specialize with <void,TRsltN> and <TRslt,void>, so I don't think I can just remove parameters without creating a conflict.

user41010
  • 91
  • 8
  • I don't understand the question. I'm not done with my morning coffee yet maybe it's that. Or maybe it's unclear. – YSC Mar 21 '22 at 07:32
  • Sorry, it produces an error: `Switcher.hpp:122:8: error: partial specialization 'struct SwitchOn), (! is_void_v)>' is not more specialized than [-fpermissive]` – user41010 Mar 21 '22 at 07:49
  • 1
    You didn't post a [mcve] (missing definition for Voidl, missing include directives) so one can only speculate. My guess is related to [Why is it disallowed for partial specialization in a non-type argument to use nested template parameters](https://stackoverflow.com/q/5978617/5470596): you cannot have template argument `! is_void_v` involving template parameter `TRslt`. – YSC Mar 21 '22 at 07:59
  • this is what I get (after adding includes): https://godbolt.org/z/99WPTao66. Please post a [mcve] and the complete error message – 463035818_is_not_an_ai Mar 21 '22 at 08:13
  • I believe I've added enough code, now. I had to use Gcc trunk in Godbolt to mirror the messages I'm getting. I have been using 12.0.1, and that's what I have easy access to other than Godbolt. – user41010 Mar 21 '22 at 08:20
  • Godbolts gives "undefined ref to main" for the linked question, so, I guess will ask a new question later, once I've done the wrapping step and have a demonstration that this is not the issue. For the moment it is 330. @YSC – user41010 Mar 21 '22 at 08:30

0 Answers0