1 year ago

#315445

test-img

user41010

Why is this partial specialization not more specialized?

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.

c++

templates

sfinae

partial-specialization

0 Answers

Your Answer

Accepted video resources