在 C++ 中使用模板和嵌套类型分离实现和声明
Separate implementation and declaration with templates and nested types in C++
如果我保持内联函数 Find(),则程序可以编译。否则如下图,编译不通过
是否可以将这样的声明和实现分开:
//////////////////////////////////////////////////////////////////////////
template <class T>
class MyClass
{
public:
struct MyStruct
{
int id;
T value;
};
MyStruct *Find(int id);
private:
};
template<class T>
MyClass<T>::MyStruct *Find(int id)
{
return nullptr;
}
//////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
MyClass<int> c;
c.Find(2);
return 0;
}
是的,有可能,as long as you keep them in the same file。如果您尝试在不同的源文件中分离定义,您很可能会以 linker 错误结束(除非您提供显式实例化并在代码中仅使用后者)。
你得到一个编译错误,因为你需要 typename
in
typename MyClass<T>::MyStruct
因为后者是 dependent name。内联情况下注入的名字MyClass<T>
是相对于实例化的,所以不需要显式指定模板参数
EDIT 正如@cocarin 提到的,您还需要限定 MyClass<T>::Find(int id)
,因为它是 MyClass<T>
的成员函数。但是,如果您不这样做,该程序仍会编译但不会 link。那是因为你最终定义了一个全局函数Find
,然后尝试调用成员函数,最终没有被定义。
您需要使用 typename
限定您的 return 值,并且实施需要限定为 MyClass
.
的成员
template<class T>
typename MyClass<T>::MyStruct * MyClass<T>::Find(int id)
{
return nullptr;
}
你应该写:
template<class T>
typename MyClass<T>::MyStruct * MyClass<T>::Find(int id)
{
return nullptr;
}
或者,自 C++11
template<class T>
auto MyClass<T>::Find(int id)
-> MyStruct* /* no need of typename MyClass<T>:: here :) */
{
return nullptr;
}
如果我保持内联函数 Find(),则程序可以编译。否则如下图,编译不通过
是否可以将这样的声明和实现分开:
//////////////////////////////////////////////////////////////////////////
template <class T>
class MyClass
{
public:
struct MyStruct
{
int id;
T value;
};
MyStruct *Find(int id);
private:
};
template<class T>
MyClass<T>::MyStruct *Find(int id)
{
return nullptr;
}
//////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
MyClass<int> c;
c.Find(2);
return 0;
}
是的,有可能,as long as you keep them in the same file。如果您尝试在不同的源文件中分离定义,您很可能会以 linker 错误结束(除非您提供显式实例化并在代码中仅使用后者)。
你得到一个编译错误,因为你需要 typename
in
typename MyClass<T>::MyStruct
因为后者是 dependent name。内联情况下注入的名字MyClass<T>
是相对于实例化的,所以不需要显式指定模板参数
EDIT 正如@cocarin 提到的,您还需要限定 MyClass<T>::Find(int id)
,因为它是 MyClass<T>
的成员函数。但是,如果您不这样做,该程序仍会编译但不会 link。那是因为你最终定义了一个全局函数Find
,然后尝试调用成员函数,最终没有被定义。
您需要使用 typename
限定您的 return 值,并且实施需要限定为 MyClass
.
template<class T>
typename MyClass<T>::MyStruct * MyClass<T>::Find(int id)
{
return nullptr;
}
你应该写:
template<class T>
typename MyClass<T>::MyStruct * MyClass<T>::Find(int id)
{
return nullptr;
}
或者,自 C++11
template<class T>
auto MyClass<T>::Find(int id)
-> MyStruct* /* no need of typename MyClass<T>:: here :) */
{
return nullptr;
}