Вы можете пометить base1<1>
, base1<2>
, base2<1>
, base2<2>
, ... одномерными целыми числами 0
, 1
, 2
, 3
, ... используя следующий шаблон класса TestsWrapper
.
Более конкретно, TestsWrapper<...T>::getIdx<U>()
возвращает позицию типа U
в пакете параметров ...T
.
Например,
TestsWrapper<A,B,C,D,E>::getIdx<A>()
- это 0
,
TestsWrapper<A,B,C,D,E>::getIdx<B>()
- это 1
,
TestsWrapper<A,B,C,D,E>::getIdx<C>()
- это 2
,
и так далее.
Это позволяет нам идентифицировать тестируемый класс как TestsWrapper<base1<1>, base1<2>, base2<1>, base2<2>>::getIdx<TypeParam>()
во время компиляции:
Live DEMO
template<class ...T>
class TestsWrapper
{
template<class U>
static constexpr std::size_t getIdx_impl()
{
return 0;
}
template<class U, class T0, class ...Ts>
static constexpr std::size_t getIdx_impl()
{
return std::is_same<U, T0>::value ? 0 : (getIdx_impl<U, Ts...>() + 1);
}
public:
using Types = ::testing::Types<T...>;
template<class U>
static constexpr std::size_t getIdx()
{
return getIdx_impl<U, T...>();
}
};
Пример использования этого шаблона класса для типизированных тестов следующий.
Здесь idx
- это вышеуказанная целочисленная метка 0
, 1
, 2
, 3
, ... и сохраняет, какой тип тестируется в настоящее время.
Вы можете использовать этот ярлык для идентификации тестируемого в данный момент класса.
Я уже проверил, что этот подход хорошо работает в моей среде Windows:
using TWrapper = TestsWrapper<base1<1>, base1<2>, base2<1>, base2<2>>;
template <typename T>
class test : public ::testing::Test {};
TYPED_TEST_CASE(test, TWrapper::Types);
TYPED_TEST(test, testname)
{
constexpr auto idx = TWrapper::getIdx<TypeParam>();
...
}