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

时间:2015-06-01 17:46:40

标签: c++ templates nested implementation

如果我保持函数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;
}

3 个答案:

答案 0 :(得分:3)

您需要使用typename限定返回值,并且实施需要被视为MyClass的成员。

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

答案 1 :(得分:1)

是的,有可能,as long as you keep them in the same file。如果您尝试在不同的源文件中分离定义,则最有可能最终会出现链接器错误(除非您提供显式实例化并在代码中仅使用后者)。

您收到编译错误,因为

中需要typename
typename MyClass<T>::MyStruct

因为后者是dependent name。在内联案例中,注入名称MyClass<T>并且它与实例化相关,因此无需显式指定模板参数。

编辑正如@cocarin所提到的,您还需要限定MyClass<T>::Find(int id),因为它是MyClass<T>的成员函数。但是,如果不这样做,程序仍将编译但不会链接。那是因为你最终定义了一个全局函数Find,然后尝试调用成员函数,最终没有被定义。

答案 2 :(得分:1)

你应该写:

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;
}