Remi.b
Remi.b

Reputation: 18219

Tag dispatch with classes

Here is a simple example of tag dispatch

template <typename T>
void foo(T x, std::true_type)
{
    std::cout << "A primitive type\n";
}

template <typename T>
void foo(T x, std::false_type)
{
    std::cout << "Not a primitive type\n";
}

template <typename T>
void foo(T x) {
    foo(x, std::is_fundamental<T>{});
}

int main()
{
    int a = 3;
    std::vector<int> v = {1,2,3};
    foo(a);
    foo(v);
    return 0;
}

I would like to do something similar but involving classes. Something like

template <typename T, std::true_type>
class C
{
public: 
    T x;
    void foo()
    {
        std::cout << "A primitive type\n";
    }

    C(T i):x(i){};
};

template <typename T, std::false_type>
class C
{
public:
    void foo()
    {
        std::cout << "Not a primitive type\n";
    }
    C(T i):x(i){};
};

int main()
{
    int a = 3;
    std::vector<int> v = {1,2,3};

    C A(a);
    C V(v);

    A.foo();
    V.foo();
    return 0;
}

but

  1. I don't know how to dispatch to the right class
  2. The statements template <typename T, std::true_type> does not compile (and I intuitively understand why).

I guess I might have to use polymorphism but I fail to wrap my head around this problem.

Upvotes: 1

Views: 1217

Answers (1)

RiaD
RiaD

Reputation: 47620

You can use (partial) specialisation. e.g

template <typename T, typename flag = typename some_trait<T>::type>
class C;


template <typename T>
class C<T, std::true_type> { //implementation if trait is true };

template <typename T>
class C<T, std::false_type> { //implementation if trait is false };

This way if you write C<some_type> default value gets determined by main template and one of specialisations is chosen

Upvotes: 6

Related Questions