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>andContainerDerived<V>(so the latter appears first), and change the forward declaration totemplate <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> *);
};
};
};
Quite a bit of complexity in these relationships. Of the main issues, you must use
typenamepreceding dependant names.