编辑:该代码已被精简为仅包含重现该错误所必需的内容。该错误发生在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'是相同类型时不会发生预期的特化。

  • 基本上,似乎添加前向声明(forward declaration)会使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> *);
            };
    
        };
    };
    

    最佳答案

    这些关系中有些复杂。在主要问题中,必须在相关名称之前使用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 *);
    };
    

    关于c++ - 从嵌套模板中遮盖祖先模板参数的前向声明,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11107756/

    10-13 03:13