Conditional specialization of functors operator()
<p>I would like to ask you for help with the programming headache I face last few days. Let me try to explain what I am about to implement...</p>

<p>My goal is to define a set of equations with its validity. Let me explain more in detail...</p>

<p>I think about being each equation object a functor - a class defining the <code>operator()</code>. The definition of this operator should be specialized for each equation type. The specialization contains the calculation itself:</p>

<p>.h:</p>

<pre><code>enum class IDs : int { A = 0, B = 1, C = 2 };

template&lt;IDs WHICH&gt;
struct Equation
{
    int operator() ( void );
}
</code></pre>

<p>.cpp:</p>

<pre><code>template&lt;&gt;
Equation&lt;IDs::A&gt;::operator()( void )
{
    /* Just some sample equation */
    return( 42 + 28 );
}
</code></pre>

<p>As you may have noticed, the specialization is defined by enum class member IDs::?.</p>

<p>This seems to be working. But I would like to add so called availability feature - The equation may be valid only for certain user object types.</p>

<pre><code>There is 'validity group' declared:
/* Object types declaration */
namespace Objects {
    using Object0 = boost::mpl::int_&lt;0&gt;;
    using Object1 = boost::mpl::int_&lt;1&gt;;
    using Object2 = boost::mpl::int_&lt;2&gt;;
}
/* Validity groups declaration */
using ValidityGroup1 = boost::mpl::vector&lt;Object0, Object2&gt;;
using ValidityGroup2 = boost::mpl::vector&lt;Object1&gt;;
</code></pre>

<p>I am using the following construct to make the class enabled or disabled (using boost::enable_if). Just to show how I use it:</p>

<pre><code>template&lt;typename TYPE_LIST, typename QUERY_TYPE&gt;
struct IsTypeInList
{
    using TypePos    = typename boost::mpl::find&lt;TYPE_LIST, QUERY_TYPE&gt;::type;
    using Finish     = typename boost::mpl::end&lt;TYPE_LIST&gt;::type;
    using type       = typename boost::mpl::not_&lt;boost::is_same&lt;TypePos, Finish&gt; &gt;::type;
    using value_type = typename type::value_type;

    static const bool value = type::value;
};

template&lt;typename OBJECT_TYPE, typename ENABLER=void&gt;
class SampleClass;

template&lt;typename OBJECT_TYPE&gt;
class SampleClass&lt;OBJECT_TYPE, typename boost::enable_if&lt;typename IsTypeInList&lt;ValidityGroup1, Object0&gt;::type&gt;::type&gt;
{}
</code></pre>

<p>The partial specialization of SampleClass is available only if <code>Object0</code> belongs to <code>ValidityGroup1</code>. So far so good. This principle is verified.</p>

<p>Now the funny stuff comes. I would like to merge the two things together:</p>

<p><strong><em>THE GOAL:</em></strong></p>

<p><strong>Define Equation's operator() who's specialization containing valid body is defined by IDs::?? enum class value" and is available only for Object belonging to ValidityGroup... There can be another calculation of the same IDs::?? but valid for Object in other ValidityGroup (aka Object0's property is calculated some other way than for Object1)</strong></p>

<p>I know the whole concept is quite complicated and may be confusing. Let me show my attempt to implement this stuff:</p>

<pre><code>template&lt;typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID, typename ENABLER = void&gt;
class Equation;

template&lt;typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID&gt;
class Equation&lt;OBJECT_TYPE, VALIDITY_GROUP, ID, typename boost::enable_if&lt;typename IsTypeInList&lt;VALIDITY_GROUP, OBJECT_TYPE&gt;::type&gt;::type &gt;
:   public EquationBase&lt;IDs&gt;
{
public:
int operator() ( void );
};

template&lt;typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID&gt;
int Equation&lt;OBJECT_TYPE, ValidityGroup1, Ids::A&gt;::operator() ( void )
{
    return( 42 + 56 );
}
</code></pre>

<p>But the operator() definition is not working... Could you please advise me how to make this working? Or does anyone have any other idea how to fulfill the goal written above?</p>

<p><strong>Many thanks</strong> in advance to anybody willing to help me...</p>

<p>Cheers Martin</p>

<p><strong><em>EDIT:</em></strong>
The equation is used in template class object. Let the code explain:</p>

<pre><code>template&lt;typename OBJECT_TYPE&gt;
class Object
{
public:
    Object( void );
};
</code></pre>

<p>.cpp:</p>

<pre><code>template&lt;typename OBJECT_TYPE&gt;
Object&lt;OBJECT_TYPE&gt;::Object( void )
{
    std::cout &lt;&lt; Equation&lt;IDs::A&gt;()() &lt;&lt; std::endl;
}
</code></pre>

<p>The problem is OBJECT_TYPE is not defined when the operators () are specialized...</p>