0

assuimng this example code

#include <vector>
#include <iostream>
#include <algorithm>
#include <unistd.h>

template< typename T, typename S >
class MyClass
{
public:
    MyClass () : v(10) {}
    bool ok () { return true; }
    T run (S s, int i) { return v.at(i) = s(); }

private:
    std::vector<T> v;
};

int main ()
{
    auto f_int = [=]() -> int { sleep(1); return 15; };
    MyClass<int, stdmc::function< int(void) > > mc_int;
    std::cout << mc_int.run(f_int, 1) << std::endl;

    return 0;
}

I want to make partial template specialization for T=void type without rewriting duplicite code. Obviously I only need to reimplement run and possibly get rid of vector as it can't store void type.

There is a lot of literature covering this topic (using enums or int template params), however not a single example of similar problems (i.e. reimplementing only one method and problematic vector).

My motivation is obvious - I need common methods written only once for future code revisions.

My attempt (using code above):

template< typename S >
class MyClass<void, S>
{
public:
    // same constructor
    // same ok() method
    void run (S s, int i) { return s(); }

private:
    // without std::vector<T> v;
};

// ----- main ------
auto f_void = [=]() -> void { sleep(1); };
MyClass<void, std::function< void(void) > > mc_void;
std::cout << mc_void.run(f_void, 1) << std::endl;

Is there any way implementing this behaviour in c++11? If so, what is the proper syntax? If not, what do you recommend - copying the whole class while correcting only one method or restructing whole class completely in order to avoid these problems (maybe use vector<T*> which should be able to store void*)?

petrbel
  • 2,428
  • 5
  • 29
  • 49
  • 3
    The parts which are independent of `T` could be moved into a base class `MyClassBase`. `MyClass` would inherit from this and extend it with parts which depend on `T`. – Oktalist May 01 '14 at 18:58

1 Answers1

0

thanks to Oktalist - this seems to work

#include <vector>
#include <iostream>
#include <algorithm>
#include <unistd.h>

class Base
{
public:
    bool ok () { return true; }
};

template< typename T, typename S >
class MyClass : public Base
{
public:
    MyClass () : v(10) {}
    T run (S s, int i) { return v.at(i) = s(); }

private:
    std::vector<T> v;
};

template< typename S >
class MyClass<void, S> : Base
{
public:
    MyClass () = default;
    void run (S s, int i) { return s(); }
};

int main ()
{
    auto f_int = [=]() -> int { sleep(1); return 15; };
    MyClass<int, std::function< int(void) > > mc_int;
    std::cout << mc_int.run(f_int, 1) << std::endl;

    auto f_void = [=]() -> void { sleep(1); std::cout << "done" << std::endl; };
    MyClass<void, std::function< void(void) > > mc_void;
    mc_void.run(f_void, 1);

    return 0;

}

Community
  • 1
  • 1
petrbel
  • 2,428
  • 5
  • 29
  • 49