c++staticparametric-polymorphism

Static member declaration in Parametrized polymorphism


I have gender class with Male and Female as my parametric types of class I am using following hierarchy:

#ifndef __GENDER_H
#define __GENDER_H

#include <string>
using namespace std;

// Forward declaration of templatized class
template<typename T>
class GenderTypes;  // Generic Gender type to generate specific genders

// Generic gender type
class Gender { // Abstract Base Class
    const string& name_; // Name of the Gender
    struct MaleType {};
    struct FemaleType {};
protected:
    Gender(const string& name) : name_(name) {}
    virtual ~Gender() { }
public:
    const string& GetName() const { return name_; }
    bool IsMale(const Gender&); // Checking and matching gender
    // Enumerated types - the target sub-types
    typedef GenderTypes<MaleType> Male;
    typedef GenderTypes<FemaleType> Female;
};

// Specific gender  types
template<typename T>
class GenderTypes : public Gender {
    static const string sName;          
    GenderTypes(const string& name = GenderTypes<T>::sName) : Gender(name) { }
    ~GenderTypes() { }
    public:
    // Singleton object - placeholder for the respective type
    static const GenderTypes<T>& Type() {
        static const GenderTypes<T> theObject;  // May be non-const for changeable behavior
        return theObject;
        }
    };
    inline bool Gender::IsMale(const Gender& g) { return &g == &Gender::Male::Type(); }
#endif 

And declaring the static member name_ as follows:

#include <string>
using namespace std;
#include "../inc/gender.h"
// Names defined as static constants
const string Gender::Male::sName = "Male";
const string Gender::Female::sName = "Female";

This kind of hierarchy is fine . then why compiler gives this error:

gender.cpp:5:14: error: specializing member ‘GenderTypes<Gender::MaleType>::sName’ requires ‘template<>’ syntax
    5 | const string Gender::Male::sName = "Male";

how should i initialize this static datas? I am using VS CODE editor and Ubuntu 20.04


Solution

  • With this small change in your .cpp it compiles (and works) fine on my machine :

    template<>
    const string Gender::Male::sName = "Male";
    
    template<>
    const string Gender::Female::sName = "Female";
    

    And indeed in your header you should use

    #ifndef GENDER_H
    #define GENDER_H
    [...]
    #endif
    

    OR

    #pragma once
    [...]