Обходной путь для выбора реализации шаблонной функции на MSVC ++ 10.0 - PullRequest
0 голосов
/ 31 марта 2020

Моя цель - выбрать другую реализацию функции на основе переменной memeber структуры данных. Я использую идиому выбора элемента "CREATE_MEMBER_DETECTOR", чтобы определить, есть ли у структуры данных определенный член. В моем случае это обнаружение базы элементов внутри struct A_t и B_t (у обоих она есть) и члена play_id внутри базы (A_t не имеет play_id). Реализация ниже работает на компиляторе MSVC ++ 14.24. Как я могу заставить его работать также на старом компиляторе MSVC ++ 10.0, который выдает тонны ошибок в Visual Studio 2010. Некоторые функции в шаблоне функции select_play_id не поддерживаются enter image description here

// templ_derive.h
#include <type_traits>
#include <cstdio>

struct A_base_t {
    int id;
};
struct A_t {
    A_base_t base;

};

struct B_base_t {
    int play_id;
};
struct B_t {
    B_base_t base;
};

#define CREATE_MEMBER_DETECTOR(X)                                                   \
template<typename T> class Detect_##X {                                             \
    struct Fallback { int X; };                                                     \
    struct Derived : T, Fallback { };                                               \
                                                                                    \
    template<typename U, U> struct Check;                                           \
                                                                                    \
    typedef char ArrayOfOne[1];                                                     \
    typedef char ArrayOfTwo[2];                                                     \
                                                                                    \
    template<typename U> static ArrayOfOne & func(Check<int Fallback::*, &U::X> *); \
    template<typename U> static ArrayOfTwo & func(...);                             \
  public:                                                                           \
    typedef Detect_##X type;                                                        \
    enum { value = sizeof(func<Derived>(0)) == 2 };                                 \
};

CREATE_MEMBER_DETECTOR(base);
CREATE_MEMBER_DETECTOR(play_id);

template<typename T, bool>
struct use_base_s {
    static void valid(T data) {
        printf("bast t \n");
    }
};

template<typename T>
struct use_base_s <T, true> {

    static void valid(T data) {
        printf("no base t \n");
    }

    // U = T and decltype(U::base) do not work!
    template<typename U = T>
    static void select_play_id(U data,
        typename std::enable_if<Detect_play_id<decltype(U::base)>::value,
        std::nullptr_t>::type = nullptr) {
        printf("has player_id t \n");
        return;
    }
    template<typename U = T>
    static void select_play_id(U data,
        typename std::enable_if<!Detect_play_id<decltype(U::base)>::value,
        std::nullptr_t>::type = nullptr) {
        printf("no player_id t \n");
        return;
    }
};

// main.cpp
#include "templ_derive.h"
int main() {
    A_t a_o = A_t();
    B_t b_o = B_t();
    use_base_s<A_t, Detect_base<A_t>::value>::select_play_id(a_o);
    use_base_s<B_t, Detect_base<B_t>::value>::select_play_id(b_o);
}

очень ценю любую помощь!

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