0

Have a simple example, with two questions related. Source code - 3 files:

parent.h:

#ifndef PARENT_H
#define PARENT_H

using namespace std;
#include <vector>

template <class CHILD_TYPE>
class PARENT
{
    public:
        class CHILD_DATA
        {
        public:
            vector<CHILD_TYPE *> child_ptrs;
            void dump_child_data();
        };
    static CHILD_DATA data;
};

template<class CHILD_TYPE>
void PARENT<CHILD_TYPE>::CHILD_DATA::dump_child_data()
{
    return;
}

#endif  /* PARENT_H */

child.h

#ifndef CHILD_H
#define CHILD_H

#include "parent.h"
using namespace std;

#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>

class SPECIAL_CHILD : public PARENT<SPECIAL_CHILD>
{
    public:
        SPECIAL_CHILD (const string newname = "unnamed") : name (newname) {}
        string name;
};

template<>
void PARENT<SPECIAL_CHILD>::CHILD_DATA::dump_child_data()
{
    for (vector<SPECIAL_CHILD *>::iterator it = child_ptrs.begin(); it != child_ptrs.end(); it++)
    {
        cout << (*it)->name << endl;;
    }
    return;
}

#endif  /* CHILD_H */

main.cpp

#include <cstdlib>
#include "parent.h"
#include "child.h"

using namespace std;

int main(int argc, char** argv) {

    SPECIAL_CHILD c_a;
    SPECIAL_CHILD c_b("named");
    SPECIAL_CHILD c_c("named_again");
    c_a.data.dump_child_data();
    return 0;
}

Question 1: this example does not build:

main.cpp:12: undefined reference to `PARENT::data'

Why? Parent's member named data is public, can't I access it from a subclass object just as an own member?

Question 2: How to create in a superclass specialized template for a subclass - in my case, with template argument being a pointer to a subclass object? I definitely don't want a superclass to know anything about subclass. Should I put the specialized template definition in subclass header, as I did? Or maybe even in subclass .cpp , if such exists?

Thanks.

Bob
  • 137
  • 1
  • 6

2 Answers2

0

For Q1, since data is a static member I think you need to access it like:

PARENT<SPECIAL_CHILD>::data.dump_child_data();
Buddy
  • 10,874
  • 5
  • 41
  • 58
0

For question 1: Add this line to one of your cpp file parent.h:

template <class CHILD_TYPE>
typename PARENT<CHILD_TYPE>::CHILD_DATA PARENT<CHILD_TYPE>::data;

--EDITED--

From N3797, article 14.5.1.3

A definition for a static data member or static data member template may be provided in a namespace scope enclosing the definition of the static member’s class template.

--END EDITED--

Question 2: Did you mean this?

class SPECIAL_CHILD : public PARENT<SPECIAL_CHILD*>
{
public:
    SPECIAL_CHILD (const string newname = "unnamed") : name (newname) {}
    string name;
};

Danh
  • 5,916
  • 7
  • 30
  • 45
  • Danh, As to question 1,I don't have cpp for subclass in my current example, I put everything to the header. I'll move all definitions from child.h to child.cpp and give it a try. As to question2 - no, I still want the supercalss template argument be a subclass, not a pointer to subclass. I'm frustrated how to define a specialized version of dump_child_data which will be specific only for SPECIAL_CHILD class. – Bob Dec 04 '15 at 19:43
  • For question 2, I can't understand what you meant. Your example described a correct specialized version of dump_child_data for only SPECIAL_CHILD – Danh Dec 07 '15 at 10:19
  • For question 2: my frustration is whether I must provide a specialized template **definition** in header file, like I do with templates, or not. I guess not, because specialized template is probably not a template anymore, but a function. When I provided specialized template definition in a header file in real project, I got linking errors stating that this function was defined multiple times - in each object file built using this header. – Bob Dec 11 '15 at 16:22
  • For the 2nd question: you can provide the specialization definition in the header file and provide definition elsewhere. Or, you can put definition in that header file and mark it `inline`. – Danh Dec 12 '15 at 05:41
  • Yes, that's what I did after all (declared specialized template function in header but moved definition to .cpp). Thank you. – Bob Dec 16 '15 at 18:57