简体   繁体   English

使用C ++中的模板和嵌套类型分别实现和声明

[英]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;
}

You need to qualify your return value with typename and the implementation needs to be qualified as a member of MyClass . 你需要与你的资格返回值typename和执行需要被定性为成员MyClass

template<class T>
typename MyClass<T>::MyStruct * MyClass<T>::Find(int id)
{
    return nullptr;
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM