Reputation: 602
I want to use 'MyType' from the base class in the 'DoesBlah' test below.
#include <gtest/gtest.h>
template <typename T>
struct MemberVariable
{
T m_t;
};
struct Base : public ::testing::Test
{
template <typename MemberType>
using MyType = MemberVariable<MemberType>;
};
template <typename DerivedType>
struct Derived : public Base
{
};
typedef ::testing::Types<int, char> MyTypes;
TYPED_TEST_CASE(Derived, MyTypes);
TYPED_TEST(Derived, DoesBlah)
{
MyType<TypeParam> test;
test.m_t = (TypeParam)1;
ASSERT_EQ(test.m_t, 1);
}
However, I get the following compilation error:
gti/specific/level/Test.t.cpp: In member function 'virtual void Derived_DoesBlah_Test<gtest_TypeParam_>::TestBody()':
gti/specific/level/Test.t.cpp:25:5: error: 'MyType' was not declared in this scope
MyType<TypeParam> test;
I tried using TestFixture::MyType, typename TestFixture::MyType, but both did not work.
How can I get Derived to recognize that there's something called 'MyType'?
Upvotes: 2
Views: 6638
Reputation: 72271
With some simplifications, the macro TYPED_TEST(Derived, DoesBlah)
expands to something like:
template <typename TypeParam>
class Derived_DoesBlah_Test : public Derived<TypeParam>
{
private:
typedef Derived<TypeParam> TestFixture;
virtual void TestBody();
};
template <typename TypeParam>
void Derived_DoesBlah_Test<TypeParam>::TestBody()
So the {}
block that follows is the function definition for a member of a template class which derives from Derived<TypeParam>
. The typedef
for TestFixture
is available, but it depends on the template parameter TypeParam
, so it is considered a dependent type. What's more, you want to access a template member of that dependent type. So you need both the typename
and template
keywords:
{
typename TestFixture::template MyType<TypeParam> test;
test.m_t = (TypeParam)1;
ASSERT_EQ(test.m_t, 1);
}
For more about dependent types and using the typename
and template
keywords in declarations and expressions, see this SO question.
Upvotes: 4