前向声明从嵌套模板中隐藏祖先模板参数

时间:2012-06-19 19:12:17

标签: c++ visual-studio-2010 templates visual-c++

编辑:代码已经过裁减,只包含重现错误所需的内容。该错误发生在const V * Resolve(const Resource<T> *);,且为error C2923: 'Resource' : 'T' is not a valid template type argument for parameter 'T'

我正在使用MSVC ++ 2010 Express来编译本文末尾显示的代码,我收到了以下错误:

1>test.cpp(119): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>          test.cpp(121) : see reference to class template instantiation 'Resource<T>::Api<U>::ContainerDerived<V>' being compiled
1>          test.cpp(136) : see reference to class template instantiation 'Resource<T>::Api<U>' being compiled
1>          test.cpp(143) : see reference to class template instantiation 'Resource<T>' being compiled
1>test.cpp(119): error C2143: syntax error : missing ',' before '&'
1>test.cpp(120): error C2923: 'Resource' : 'T' is not a valid template type argument for parameter 'T'

(代码中的第119行是:std::auto_ptr<Dependent<V> > Construct(const T &);

似乎前向声明template <typename V> class ContainerDerived;导致ContainerDerived的定义失去祖先类Resource<T>中T参数的'可见性'。

这是我尝试过的:

  • 切换Dependent<V>ContainerDerived<V>的定义顺序(因此后者首先出现),并将前向声明更改为template <typename V> class Dependent;。这修复了ContainerDerived但导致与Dependent相同的问题。
  • 在任一定义之前添加typedef T FooBar;,并在Dependent / ContainerDerived的两个/两个中将'T'的所有实例切换为'FooBar'。这会编译,但是当'T'和'V'是相同类型时,预期的专业化不会发生。

基本上,似乎添加某个东西的前向声明会使T参数从其定义中模糊不清。任何人都知道为什么会这样?

以下是代码:

#include <memory>

template <typename TypeContainer, typename TypeContained>
class Proxy
{
public:
    class Container {};

    Proxy(TypeContainer * = NULL);
    Proxy(Proxy &);
    ~Proxy();
};

struct Dummy {};

template <typename T>
class Resource : public T, public Proxy<Resource<T>, Dummy>::Container
{
public:

    template <typename U>
    class Api
    {
    public:

        template <typename V> class ContainerDerived;

        template <typename V>
        class Dependent : public Proxy<ContainerDerived<V>, Dependent<V> > {};

        template <typename V>
        class ContainerDerived
        {
        public:
            const V * Resolve(const Resource<T> *);
        };

    };
};

1 个答案:

答案 0 :(得分:1)

这些关系有点复杂。在主要问题中,您必须使用typename前面的从属名称。

template <typename V>
class ContainerDerived : public ContainerBase<ContainerDerived<V>, Dependent<V> >
{
public:
        typedef typename Api::Dependant<V> DV;
        typedef typename Resource::T TX;
    std::auto_ptr<DV> Construct(const TX &);
        typedef Resource<typename Resource::T> TR;
    const V * Resolve(const TR *);
};