0

I want to create typesafe structures that are basically identical but have different types so that they require different function signatures.

struct A {
    Time t;
    void doStuff(const A&);
    A getStuff();
};

struct B {
    Time t;
    void doStuff(const B&);
    B getStuff();
};

If I sue a template for the class

template<class T>
struct X {
    Time t;
    void doStuff(const X&);
    X getStuff();
};

how can I make functions typesafe and define function signatures differently for a struct X of type A and a struct X of type B?

iBug
  • 35,554
  • 7
  • 89
  • 134
chrise
  • 4,039
  • 3
  • 39
  • 74
  • 1
    Your template looks wrong. You should write `doStuff(const X&);` and `X getStuff();`. – iBug Oct 05 '17 at 01:22
  • 1
    thanks. edited question – chrise Oct 05 '17 at 01:23
  • Another bug: What's the return type of `doStuff()`? – iBug Oct 05 '17 at 01:27
  • 1
    It's not at all clear what you're asking. The code you have is almost valid (except for the missing return type already mentioned, and some missing semicolons). How do you want to use the types and/or the template, or what is it you want to add or change about them that you haven't shown? – aschepler Oct 05 '17 at 01:30
  • @aschepler I think it's clear enough. The OP mentioned "typesafe" several times. – iBug Oct 05 '17 at 01:39

2 Answers2

1

Try adding some unused template parameters.

template <int>
struct X{
    Time t;
    void doStuff(const X&); // You missed return type
    X getStuff();
}; // You missed a semicolon

// Great thanks to "aschepler"

And now you can (C++11 syntax)

using A = X<1>;
using B = X<2>;
// typedef X<1> A;
// typedef X<2> B;

The following code will fail, which is what you want:

A a; B b;
a.doStuff(b); // Fail
a = b.getStuff(); // Fail
iBug
  • 35,554
  • 7
  • 89
  • 134
0

You could use a combination of Inheritance and template for that.
Following your line of thought, a possible code is:

template <class T> struct X {
    int time = 10;
    virtual void doStuff(const T&) = 0;
    virtual T getStuff() = 0;
};

struct A : X<A>
{
    void doStuff(const A& a) {
        cout << "Do A stuff" << endl;
    }

    A getStuff() {
        return *this;
    }
};

struct B : X<B>
{
    void doStuff(const B& value) {
        cout << "Do B stuff" << endl;
    }

    B getStuff() {
        return *this;
    }
};

Then, testing we have:

int main()
{
    A a; B b;

    a.doStuff(a);  // Ok
    b.doStuff(b);  // Ok
    a.doStuff(b);  // fail
    b.doStuff(a);  // fail
    b = b.getStuff();  // Ok
    b = a.getStuff();  // fail

    return 0;
}
tonyamjr
  • 11
  • 6