Here's my code:
#include <iostream>
template <typename T>
struct Foo
{
public:
T DataMember;
};
template<>
struct Foo<int>
{
public:
void bar()
{
std::cout << DataMember;
}
};
When I try to compile it, it gives an
error C2065 'DataMember': undeclared identifier
What I want to do is to use templates members in its specialization.
I tried a lot of things and googled the problem for hours, but everything I find is examples that don't use templates members and other questions related to c++ templates, but not the one I need.
You have mixed up the concept of inheritance and class template specialization. When you specialize Foo
for int
, you are instructing the compiler to disregard the generic template definition entirely and instead focus solely on the specialized version provided for Foo<int>
. The template<> struct Foo<int>
has hence no DataMember
; therefore the compiler error!
Depending upon the use case, you might end up mainly
either SFINAE (Substitution Failure Is Not An Error) (Since you are using C++14) along with template specialization.
#include <type_traits> // For std::enable_if
// Primary template for Foo
template <typename T, typename = void> struct Foo
{
T DataMember;
};
// Specialization for Foo<int> with a bar() member function
template <typename T>
struct Foo<T, std::enable_if_t<std::is_same<T, int>>
{
T DataMember; // you have to repeat "DataMember" here!
void bar()
{
std::cout << DataMember;
}
};
or You can use std::enable_if
(i.e. SFINAE) directly within the primary template to conditionally enable the bar()
member function based on the type T
.
template <typename T>
struct Foo
{
T DataMember;
// Enable bar() only for T being int
template <typename U = T
, std::enable_if_t<std::is_same<U, int>::value>* = nullptr>
void bar()
{
std::cout << DataMember;
}
};
In c++17, you could use if-constexpr, and since c++20 you would use much elegant concepts for the above.