Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forward declaration obscuring ancestor template parameter from nested template

EDIT: the code has been trimmed down to contain only what is necessary to reproduce the error. The error occurs at const V * Resolve(const Resource<T> *); and is error C2923: 'Resource' : 'T' is not a valid template type argument for parameter 'T'.

I'm using MSVC++ 2010 Express to compile the code displayed at the end of this post and I get these errors:

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'

(line 119 in the code is this: std::auto_ptr<Dependent<V> > Construct(const T &);)

It seems that the forward declaration template <typename V> class ContainerDerived; causes the definition of ContainerDerived to lose 'visibility' of the T parameter in the ancestor class Resource<T>.

Here is what I've tried:

  • Switch the definition order of Dependent<V> and ContainerDerived<V> (so the latter appears first), and change the forward declaration to template <typename V> class Dependent;. This fixes ContainerDerived but causes the same issue with Dependent.
  • Add typedef T FooBar; prior to either definition and switch all instances of 'T' to 'FooBar' in either/both of Dependent/ContainerDerived. This compiles, but the intended specialization when 'T' and 'V' are the same type does not occur.

Basically, it seems like adding a forward declaration of something is obscuring the T parameter from its definition. Anyone have any idea why this occurs?

Here is the code:

#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> *);
        };

    };
};
like image 870
jorgander Avatar asked Jun 18 '26 19:06

jorgander


1 Answers

Quite a bit of complexity in these relationships. Of the main issues, you must use typename preceding dependant names.

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 *);
};
like image 115
John Dibling Avatar answered Jun 21 '26 10:06

John Dibling



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!