Получить тип члена данных на C ++ 03 во время компиляции - PullRequest
0 голосов
/ 09 марта 2019

Следующий код пытается смоделировать общую таблицу с различными типами для записей (где каждая запись содержит ключ и значение).
В функции «compareKeyWithEntry ()» нам нужно использовать тип связанного ключа в качестве сигнатуры функции-члена; для этого используется decltype.

#include <iostream>

struct Key {
    int a;
};

bool operator ==(const Key &key_1, const Key &key_2) {
    return  ( key_1.a == key_2.a );
}

struct Value {
    int b;
};

struct Entry {
    Key key;  
    Value val;
};


template <typename Entry>
class Table 
{
public:

    Table(){}

    template <typename Key_T = decltype(Entry::key)>
    bool compareKeyWithEntry(const Entry& entry, const Key_T& key) {
        return operator==(entry.key, key);
    } 
};

int main()
{
    Entry e = { { 1, 2} };

    Table<Entry> table;
    std::cout << table.compareKeyWithEntry(e, e.key) << std::endl;
}

Текущий код функционален и достигает цели. Но возможно ли получить тот же результат без «decltype»? (с использованием C ++ 03)

1 Ответ

0 голосов
/ 09 марта 2019

Вы не можете получить тип члена, но с помощью SFINAE можно добиться того, чего вы хотите, просто спросив, совпадает ли какой-либо тип с типом члена.

typedef char yes_type;
struct no_type { char arr[2]; };

template <typename Key, typename Entry>
struct is_key_of
{
private:
    static yes_type test(Key Entry::*);
    static no_type  test(...);

public:
    static bool const value = sizeof(test(&Entry::key)) == sizeof(yes_type);
};

template <bool> struct static_assertion;
template <>     struct static_assertion<true> {};
#define OWN_STATIC_ASSERT(x) ((void)static_assertion<(x)>())


struct Key {
    int a;
};

bool operator ==(const Key &key_1, const Key &key_2) {
    return  ( key_1.a == key_2.a );
}

struct Value {
    int b;
};

struct Entry {
    Key key;  
    Value val;
};


template <typename Entry>
class Table 
{
public:

    Table(){}

    template <typename Key_T>
    bool compareKeyWithEntry(const Entry& entry, const Key_T& key) {
        OWN_STATIC_ASSERT((is_key_of<Key_T, Entry>::value));
        return operator==(entry.key, key);
    } 
};

int main()
{
    Entry e = { { 1 }, { 2 } };

    Table<Entry> table;
    table.compareKeyWithEntry(e, e.key);
    //table.compareKeyWithEntry(e, 0); // static assertation raises
}

https://godbolt.org/z/V_N9ME

Вы можете заменить статическую диссертацию на enable_if в типе возврата, если хотите устранить перегрузку, как в вашем вопросе decltype.

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