-1

I have a project with multiple specializations but I need some "BasicStuff" in each of the specializations. Problem: I need to use some templates because only the specialization knows how some objects look like.

For Example I have some class "BasicData", "BasicDataHolder" and "BasicDataManager" where BasicData will be a class with timestamps. BasicDataHolder would hold the BasicData like a vector but with some more functions. The BasicDataManager would do stuff with multiple Objects of the BasicDataHolder.

Now the problem:

In the each of the specializations I have some "SpecialData" which is derived from BasicData. And I have to use sometime a BasicDataManager1 and in another specialization a BasicDataManager2 which are both derived from the BasicDataManager.

Unfortunatly templates are like voodoo for me but I tried it as the following:

    // BasicData.hpp
    class BasicData {
        int foo;
    };

    // BasicDataHolder.hpp
    template< typename T>
    class BasicDataHolder {
        static_assert(std::is_base_of<BasicData, T>::value, "!");
        vector<T> data;
        // other stuff
    };

    // BasicDataManager.hpp
    template <class T>
    // I tried something like template <template T> but it tells me
    // error: expected '<' before 'T'
    class BasicDataManager {
        // This Line is a problem
        static_assert(std::is_base_of<BasicDataHolder, T>::value, "!");
        vector<T> holderVector;
        // stuff
    };

    // specialDataManager
    template <class T>
    class SpecialDataManager : public BasicDataManager<T> {
        T dostuff();
        // other stuff
    };

    //specialDataHolder
    template <class T>
    class SpecialDataHolder : public BasicDataHolder<T> {
        // do some stuff
    };

    // Specialization:
    //specialData.hpp
    template <typename T>
    class SpecialData : public T {
        static_assert(std::is_base_of<BasicData, T>::value, "!");
        double bar;
        //other stuff
    };

Now I have to initialize the SpecialDataManager in my project-specialization. I tried it like

    // main.cpp
    #include "specialData.hpp
    #include "specialDataManager.hpp
    #include "specialDataHolder.hpp
    // This line is my problem, I think
    SpecialDataManager<SpecialDataHolder<SpecialData> > myManager;

I get multiple lines of error like: "error: 'SpecialDataManager' does not name a type"

My real problem is a dimension more but I think if I can solve this, it should be no problem anymore. Can someone help? I am not sure where I made any mistake...

  • I think the real problem could be the "class should be derived from ..." stuff in the templates. – Henrik Viebrock Oct 06 '17 at 14:23
  • @FrançoisAndrieux All those definitions are in seperate files and have a simicolon at the end. I just forgot to put it in the pseudo code above. – Henrik Viebrock Oct 06 '17 at 14:24
  • Avoid to use same name for class and template argument: `class BasicData;` and `template< template class Tdata> class ..` – Jarod42 Oct 06 '17 at 14:29
  • `std::vector` is invalid as `Tdata` is not a type (but a template). (do you mean `std::vector >` ?) – Jarod42 Oct 06 '17 at 14:31
  • @Jarod42 wait. I thought template – Henrik Viebrock Oct 06 '17 at 14:37
  • @HenrikViebrock: No, those are called "template template" parameters, and it means that `Tdata` is itself templated. – AndyG Oct 06 '17 at 14:47
  • @Jarod42 Ok, I replace all of those template templates by `template `. Now I am trying to do something link `template class specialManager: public Tmanager >` but now it says `expected template-name before '<' token class specialManager: public Tmanager >` – Henrik Viebrock Oct 06 '17 at 14:53

1 Answers1

0

It seems you want something like:

class BasicData {
    int foo;
    // other stuff
};

template <typename T>
class BasicDataHolder {
    static_assert(std::is_base_of<BasicData, T>::value, "!");
    using data = vector<T>;
    data mData;
    // other stuff
};

template <class T>
class BasicDataManager {
    using holderVector = vector<T>;
    holderVector mData;
    // stuff
};

template <class T>
class SpecialDataManager : public BasicDataManager<T> {
    T dostuff();
    // other stuff
};

template <typename T>
class SpecialDataHolder : public BasicDataHolder<T> {
    // do some stuff
};

template <template T>
class SpecialData : public T {
    static_assert(std::is_base_of<BasicData, T>::value, "!");

    double bar;
    //other stuff
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • There seem to be a mistake. I always get the message `error: type/value mismatch at argument 1 in template parameter list for 'template struct std::is_base_of' static_assert(std::is_base_of::value, "!"); error: expected a type, got 'BasicHolder' ` – Henrik Viebrock Oct 06 '17 at 15:32
  • Your answer has another problem: I will explizitly define, that the BasicDataManager manage Objects of BasicHolder. Maybe there I need a Template template or something? – Henrik Viebrock Oct 06 '17 at 15:35
  • Can you edit your question to show how you (want to) use it. – Jarod42 Oct 06 '17 at 15:40
  • I think I have problems because I have to derive a second time from that stuff... I have a BasicDataManager, a SpecialDataManager AND a SpecialManager which should be make it more easier to use... But I dont think it works as I want it to work... – Henrik Viebrock Oct 06 '17 at 15:56
  • Why should be the specialData use a template template? Why not just a typename or so? – Henrik Viebrock Oct 06 '17 at 16:19
  • Your usage should be `SpecialDataManager > >`. – Jarod42 Oct 06 '17 at 16:43
  • I tried to make the BasicDataManager check that T is a derived class from BasicDataHolder. Therefor I have a more complex call like: `SpecialDataManager, SpecialData >` – Henrik Viebrock Oct 06 '17 at 16:49
  • But now the linker does not like me: undefined reference to `SpecialDataManager >, SpecialData >::someFunction()'` **Edit:** It sees to be that I got the error mentions here: https://stackoverflow.com/a/8752879/6486348 – Henrik Viebrock Oct 06 '17 at 16:52
  • All implementations should be in header, not in cpp. – Jarod42 Oct 06 '17 at 16:55
  • I Included my cpp files at the end of my hpp file and removed them from my makefile. Thats a "quick and dirty" solution. – Henrik Viebrock Oct 06 '17 at 17:38
  • Rename them ".inl"/hxx to no longer be dirty. – Jarod42 Oct 06 '17 at 17:40
  • I named them hpp_inc – Henrik Viebrock Oct 08 '17 at 10:30