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

查看:159
本文介绍了为什么这个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:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>'
1>        with
1>        [
1>            InInternalType=DataClass
1>        ]
1>        e:\test\generaltestprogram\generaltestprogram\main.cpp(35) : see reference to class template instantiation 'Base<DerivedType>' being compiled
1>        with
1>        [
1>            DerivedType=Derived<DataClass>
1>        ]
1>        e:\test\generaltestprogram\generaltestprogram\main.cpp(58) : see reference to class template instantiation 'Derived<InInternalType>' being compiled
1>        with
1>        [
1>            InInternalType=DataClass
1>        ]
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C2146: syntax error : missing ';' before identifier 'ThisFunctionDoesNotCompile'
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(28) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(28) : warning C4183: 'ThisFunctionDoesNotCompile': missing return type; assumed to be a member function returning 'int'

这些是GCC给我的:

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< DataClass> > 是 Derived< DataClass> 的父类,必须在 Derived< DataClass> 可以实例化。所以当类 Base< Derived< DataClass> > 从模板构建, Derived< DataClass> 的行为好像是一个向前声明。而且你可能知道,你不能引用不完整类型的成员,也不能向前声明嵌套类型,所以你在这里运气不好。

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天全站免登陆