Моя цель - выбрать другую реализацию функции на основе переменной 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 не поддерживаются
// 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);
}
очень ценю любую помощь!