[英]Separate implementation and declaration with templates and nested types in C++
If I keep the function Find() inlined, then the program compiles. 如果我保持函数Find()内联,则程序将编译。 Otherwise, as shown below, it does not compile.
否则,如下所示,它将无法编译。
Is it possible to separate the declaration and implementation of such: 是否可以将这样的声明和实现分开:
//////////////////////////////////////////////////////////////////////////
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;
}
Yes, it is possible, as long as you keep them in the same file . 是的,有可能, 只要将它们保存在同一文件中即可 。 If you try to separate the definition in a different source file, you'll most likely going to end up with linker errors (unless you provide explicit instantiations and use only the latter in your code).
如果尝试将定义分隔到其他源文件中,则很可能会出现链接器错误(除非您提供显式实例化,并且在代码中仅使用后者)。
You get a compile error because you need typename
in 您收到编译错误,因为您需要输入
typename
typename MyClass<T>::MyStruct
as the latter is a dependent name . 因为后者是一个从属名称 。 In the inline case, the name
MyClass<T>
is injected and it is relative to the instantiation, so there is no need to explicitly specify the template parameter. 在内联情况下,将注入名称
MyClass<T>
,并且名称是相对于实例化的,因此无需显式指定template参数。
EDIT As @cocarin mentioned, you also need to qualify MyClass<T>::Find(int id)
, since it is a member function of MyClass<T>
. 编辑正如@cocarin所述,您还需要限定
MyClass<T>::Find(int id)
,因为它是MyClass<T>
的成员函数。 However, if you don't, the program will still compile but won't link. 但是,如果不这样做,该程序仍将编译但不会链接。 That's because you end up defining a global function
Find
, then try to invoke the member function, which ends up not being defined. 那是因为您最终定义了一个全局函数
Find
,然后尝试调用该成员函数,但最终未定义该成员函数。
You should write: 您应该写:
template<class T>
typename MyClass<T>::MyStruct * MyClass<T>::Find(int id)
{
return nullptr;
}
or, since C++11 或者,因为C ++ 11
template<class T>
auto MyClass<T>::Find(int id)
-> MyStruct* /* no need of typename MyClass<T>:: here :) */
{
return nullptr;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.