Перегрузка enum в дочернем классе в c ++ - PullRequest
0 голосов
/ 25 января 2019

Я заинтересован в определении общего класса для наследования, который работает по-разному на основе перечисления и сопоставления этого перечисления с некоторой структурой данных.

В следующем коде у меня есть наследование test_child от test_parent, в котором уже реализованы общие функции. Мой план состоял бы в том, чтобы многие классы наследовали от такого класса, как parent_class, но определяли уникальное перечисление 'field' и соответствующую карту 'mapping'.

#include <iostream>
#include <string>
#include <unordered_map>

class test_parent {
public:
    enum class field {
        A,
        B,
        C
    };

    typedef struct {
        std::string s;
        int i, j;
    } data_t;

    std::unordered_map<field, data_t> mapping {
        {field::A, {"A", 1, 1}},
        {field::B, {"B", 2, 2}},
        {field::C, {"C", 3, 3}}
    };

    int get_i (field f) {
        return mapping[f].i;
    }

    std::string get_s (field f) {
        return mapping[f].s;
    }   
};

class test_child : test_parent {
public:
    enum class field {
        D,
        E
    };

    std::unordered_map<field, data_t> mapping {
        {field::D, {"D", 4, 4}},
        {field::E, {"E", 5, 5}}
    };
};

int main () {
    test_parent tp;
    test_child tc;

    std::cout << tp.get_i(test_parent::field::A) << " " << tc.get_i(test_child::field::E) << std::endl;

    return 0;
}

Этот код возвращает ошибку компиляции:

test.cpp: In function ‘int main()’:
test.cpp:55:86: error: no matching function for call to ‘test_child::get_i(test_child::field)’
std::cout << tp.get_i(test_parent::field::A) << " " << tc.get_i(test_child::field::E) << std::endl;
                                                                                    ^
test.cpp:28:6: note: candidate: int test_parent::get_i(test_parent::field)
int get_i (field f) {
    ^~~~~
test.cpp:28:6: note:   no known conversion for argument 1 from ‘test_child::field’ to ‘test_parent::field’

Но то, что я ожидаю, будет напечатано:

1 5

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Привет. Я думаю, что, возможно, я нашел ответ в следующем примере:

#include <iostream>
#include <string>
#include <unordered_map>

class test_parent {
public:
    enum class field {
        A,
        B,
        C
    };

    typedef struct {
        std::string s;
        int i, j;
    } data_t;

    std::unordered_map<uint, data_t> mapping {
        {(uint) field::A, {"A", 1, 1}},
        {(uint) field::B, {"B", 2, 2}},
        {(uint) field::C, {"C", 3, 3}}
    };

    int get_i (uint f) {
        return mapping[f].i;
    }

    std::string get_s (uint f) {
        return mapping[f].s;
    }   
};

class test_child : public test_parent {
public:
    test_child () {
        test_parent::mapping = mapping;
    }

    enum class field {
        D = 4,
        E = 5
    };

    std::unordered_map<uint, data_t> mapping {
        {(uint) field::E, {"E", 5, 5}},
        {(uint) field::D, {"D", 4, 4}}
    };
};

int main () {
    test_parent tp;
    test_child tc;

    std::cout << tp.get_i((uint) test_parent::field::A) << " " << tc.get_i((uint) test_child::field::E) << std::endl;

    return 0;
}

Где я трактую значения enum такими, какими они изначально были, целые числа!

0 голосов
/ 25 января 2019

Не уверен, что это то, что вы хотите, но с шаблоном вы можете сделать

struct data_t
{
    std::string s;
    int i;
    int j;
};

template <typename E>
class test_parent {
public:
    int get_i(E e) const { return mapping.at(e).i; }
    const std::string& get_s(E e) const { return mapping.at(e).s; }

    static const std::unordered_map<E, data_t> mapping;
};

А затем

enum class field_ABC{ A, B, C };
enum class field_DE{ D, E };

template <>
const std::unordered_map<field_ABC , data_t> test_parent<field_ABC >::mapping =  {
    {field_ABC::A, {"A", 1, 1}},
    {field_ABC::B, {"B", 2, 2}},
    {field_ABC::C, {"C", 3, 3}}
};

template <>
const std::unordered_map<field_DE, data_t> test_parent<field_DE>::mapping =  {
    {field_DE::D, {"D", 4, 4}},
    {field_DE::E, {"E", 5, 5}}
};

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...