为什么这个 C++ 模板代码不能编译? [英] Why doesn't this C++ template code compile?

查看:31
本文介绍了为什么这个 C++ 模板代码不能编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道为什么这不能编译?我已经尝试过 VS 2008 和 GCC 4.something 并且都吐出错误.我是否引用ThisFunctionDoesNotCompile()"并不重要.

Does anyone know why this will not compile? I've tried both VS 2008 and GCC 4.something and both spit out errors. It doesn't matter whether or not I'm referencing "ThisFunctionDoesNotCompile()".

我可以通过将InternalType"作为第二个模板参数传递给 Base 来解决此问题,但我仍然很好奇为什么会出现错误.

I can workaround this by just passing 'InternalType' as a second template parameter to Base, but I'm still curious why this comes up as an error.

#include <iostream>
using namespace std;

class DataClass
{
public:
    int m_data;
};

template<typename DerivedType>
class Base
{
public:
    int ThisFunctionCompiles()
    {
        // No problems here.

        typename DerivedType::InternalType temp;
        temp.m_data = 5;
        return temp.m_data;
    }

    // error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>'
    typename DerivedType::InternalType ThisFunctionDoesNotCompile()
    {
        return static_cast<DerivedType*>(this)->GetInternalData();
    }
};

template<typename InInternalType>
class Derived : public Base<Derived<InInternalType> >
{
public:
    typedef InInternalType InternalType;

    InternalType GetInternalData()
    {
        return m_internalData;
    }

private:
    InternalType m_internalData;


public:
    void SetInternalData( int newVal )
    {
        m_internalData.m_data = newVal;
    }
};

int main()
{

    Derived<DataClass> testDerived;
    testDerived.SetInternalData( 3 );

    cout << testDerived.GetInternalData().m_data << endl;
    cout << testDerived.ThisFunctionCompiles() << endl;

    // The compiler gives an error regardless of whether or not this is commented out.
    //cout << testDerived.ThisFunctionDoesNotCompile().m_data << endl;

    return 0;
}

这些是我在 VS 2008 中遇到的错误:

These are the errors I get in VS 2008:

1>e:	estgeneraltestprogramgeneraltestprogrammain.cpp(27) : error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>'
1>        with
1>        [
1>            InInternalType=DataClass
1>        ]
1>        e:	estgeneraltestprogramgeneraltestprogrammain.cpp(35) : see reference to class template instantiation 'Base<DerivedType>' being compiled
1>        with
1>        [
1>            DerivedType=Derived<DataClass>
1>        ]
1>        e:	estgeneraltestprogramgeneraltestprogrammain.cpp(58) : see reference to class template instantiation 'Derived<InInternalType>' being compiled
1>        with
1>        [
1>            InInternalType=DataClass
1>        ]
1>e:	estgeneraltestprogramgeneraltestprogrammain.cpp(27) : error C2146: syntax error : missing ';' before identifier 'ThisFunctionDoesNotCompile'
1>e:	estgeneraltestprogramgeneraltestprogrammain.cpp(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:	estgeneraltestprogramgeneraltestprogrammain.cpp(28) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:	estgeneraltestprogramgeneraltestprogrammain.cpp(28) : warning C4183: 'ThisFunctionDoesNotCompile': missing return type; assumed to be a member function returning 'int'

这些是 GCC 给我的:

And these are what GCC gives me:

main.cpp: In instantiation of 'Base<Derived<DataClass> >':
main.cpp:96:   instantiated from 'Derived<DataClass>'
main.cpp:119:   instantiated from here
main.cpp:88: error: no type named 'InternalType' in 'class Derived<DataClass>'

推荐答案

当模板化类 Base 被实例化为类 Derived 的父类时,类 Derived 并不是一个完整的类型.

At the time that the templated class Base is instantiated as a parent of the class Derived, the class Derived is not a complete type.

由于 Base>Derived的父类,必须先实例化,Derived才能实例化.所以当类 Base;> 是从模板构建的,Derived 的行为就像是一个前向声明.正如您可能知道的那样,您不能引用不完整类型的成员,也不能引用前向声明的嵌套类型,因此您在这里很不走运.

Since Base<Derived<DataClass> > is a parent class of Derived<DataClass>, it must be instantiated before Derived<DataClass> can be instantiated. So when the class Base<Derived<DataClass> > is built from the template, Derived<DataClass> behaves as if it were a forward declaration. And as you're probably aware, you can't reference members of incomplete types, nor can your forward-declare nested types, so you're out of luck here.

顺便说一下,这就是为什么很难使用模板实现适当的协变 clone() 方法的原因.请参阅此处这里(我的).

This, by the way, is why it's difficult to implement a properly covariant clone() method using templates. See here and here (mine).

这篇关于为什么这个 C++ 模板代码不能编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆