这是我的代码:
#include <iostream>
template <typename T>
struct Foo
{
public:
T DataMember;
};
template<>
struct Foo<int>
{
public:
void bar()
{
std::cout << DataMember;
}
};
当我尝试编译它时,它给出了一个
error C2065 'DataMember': undeclared identifier
我想做的是在其专业化中使用模板成员。
我尝试了很多方法,并在谷歌上搜索了几个小时的问题,但我找到的所有内容都是不使用模板成员的示例以及与 c++ 模板相关的其他问题,但不是我需要的。
您混淆了继承和类模板专业化的概念。当您将
Foo
专门化为 int
时,您将指示编译器完全忽略通用模板定义,而仅关注为 Foo<int>
提供的专用版本。因此 template<> struct Foo<int>
没有 DataMember
;因此编译器错误!
根据用例,您可能最终会主要
SFINAE(替换失败不是错误)(因为您使用的是 C++14)以及模板专门化。
#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;
}
};
或者您可以直接在主模板中使用
std::enable_if
(即 SFINAE),根据类型 bar()
有条件地启用 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;
}
};
在 c++17 中,您可以使用 if-constexpr,从 c++20 开始,您将使用更多优雅的 concept 来实现上述内容。