C ++ typedef with nested templates is not a class, structure, or union type

I am not sure to understand why the following code is not compiled with g ++:

t.cpp: In instantiation of 'Distrib<double>': t.cpp:28:56: instantiated from 'Sampler<Distrib<Solution<double> > >' t.cpp:35:48: instantiated from here t.cpp:16:45: erreur: 'double' is not a class, struct, or union type t.cpp:18:43: erreur: 'double' is not a class, struct, or union type 

I expected to be able to propagate the AtomType type over nested templates ...

 #include <iostream> #include <vector> template<typename T> class Solution { public: typedef T AtomType; }; template<typename SOLT> class Distrib { public: typedef typename SOLT::AtomType AtomType; typedef std::vector<AtomType> Matrix; Matrix matrix; }; template<typename DT> class Sampler { public: typedef typename DT::AtomType AtomType; typedef typename Distrib<AtomType>::Matrix Matrix; Matrix matrix; }; int main() { Sampler< Distrib< Solution<double> > > sampler; } 
+4
source share
4 answers

In your Sampler class, you have:

 typedef typename Distrib<AtomType>::Matrix Matrix; 

Here AtomType is double , so this is

 typedef typename Distrib<double>::Matrix Matrix; 

And then in your class Distrib

 typedef typename SOLT::AtomType AtomType; 

expands to

 typedef typename double::AtomType AtomType; 

Hence the error message. I think you want the string in the Sampler class to be:

 typedef typename DT::Matrix Matrix; 
+2
source

In your Distrib template, you have the following typedef

 typedef typename SOLT::AtomType AtomType; 

This means that any type that you pass as a template parameter must have AtomType as a member, and double does not have such a thing.

If you made such a class

 class Double { typedef myType AtomType; }; 

and passed this as a template parameter to your Distrib template, it will compile since Double::AtomType exists.

+4
source

Matrix Distrib typedef in the Distrib class uses AtomType , but we would expect DT :

 typedef typename Distrib<DT>::Matrix Matrix; 

The compiler saw double spread through nested templates.

+1
source

Distrib is a pattern of type Solution ; but in the definition of Sampler::Matrix you use AtomType as the template argument. Presumably, you just need the Distrib type, which was provided as Sampler :

 template<typename DT> class Sampler { // ... typedef typename DT::Matrix Matrix; }; 
+1
source

All Articles