简体   繁体   中英

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

I'm 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 was expecting to be able to propagate the AtomType type across the 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;
}

In your Distrib template you have the following typedef

typedef typename SOLT::AtomType AtomType;

Which means that any type you pass in as a template parameter, must have a AtomType as a member, and double has no such thing.

If you made a class like so

class Double
{
   typedef myType AtomType;
};

and passed that in as a template parameter to your Distrib template, it would compile, as Double::AtomType does exist.

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 Distrib class, the line

typedef typename SOLT::AtomType AtomType;

expands to

typedef typename double::AtomType AtomType;

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

typedef typename DT::Matrix Matrix;

The Matrix typedef in the Distrib class is using AtomType , but what we would expect was a DT :

typedef typename Distrib<DT>::Matrix Matrix;

The compiler was seeing the double propagated across nested templates.

Distrib is templated over the type of Solution ; but in the definition of Sampler::Matrix you're using AtomType as the template argument. Presumably, you just want the type of Distrib that was provided as to the Sampler :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM