-4

this is related to these two questions:

  1. standard c++11 way to remove all pointers of a type
  2. Compile Time Template restriction C++

the second one is mine

the issue is when i moved to TDM-GCC 64 the following code (previously working) does not compile I made sure c++11 is enabled.

I took the remove_all_pointers from the first question, and combined it with the answer to my question(bullet #2).

The following is my (previously) compilable example

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T> class remove_all_pointers{
public:
    typedef T type;
};

template <typename T> class remove_all_pointers<T*>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* const>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* volatile>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* const volatile >{
public:
    typedef typename remove_all_pointers<T>::type type;
};


class OverVoid{
public:

    static bool isOverVoid (){
    return true;
    }
    virtual ~OverVoid(){
    }
};

class Meta: public OverVoid{

};

class Physical{
public:

};

template<typename _Ty,typename = typename std::enable_if<std::is_base_of<OverVoid, remove_all_pointers<_Ty>::type>::value>::type>

class Move{
public:
    Move()
    {
        cout<<"### "<<remove_all_pointers<_Ty>::type::isOverVoid()<<endl;
    }
};


template<typename _Ty,typename = typename std::enable_if<std::is_base_of<OverVoid, remove_all_pointers<_Ty>::type>::value>::type>

class Move{
public:
    Move()
    {
        cout<<"### "<<remove_all_pointers<_Ty>::type::isOverVoid()<<endl;
    }
};




    template<typename _Ty,
    typename enable_if< is_base_of<OverVoid, remove_all_pointers<_Ty>::type>::value>::type>
    class Move{
    public:
        Move()
        {
            cout<<"### "<<remove_all_pointers<_Ty>::type::isOverVoid()<<endl;
        }
    };


    int main(){

        Move<Meta***> z;
        Move<Meta**> w;
        Move<Meta*> x;
        Move<Meta> y;

    }

it displays the following error

Info: Internal Builder is used for build
g++ -std=c++0x -std=c++11 -std=gnu++11 -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\helllo_world.o" "..\\src\\helllo_world.cpp" 
In file included from ..\src\helllo_world.cpp:1:0:
..\src\Move.h:54:111: error: type/value mismatch at argument 2 in template parameter list for 'template<class, class> struct std::is_base_of'
 template<typename _Ty,class = typename std::enable_if<std::is_base_of<OverVoid, remove_all_pointers<_Ty>::type>::value>::type>
                                                                                                               ^
..\src\Move.h:54:111: note:   expected a type, got 'remove_all_pointers<T>::type'
..\src\Move.h:54:119: error: template argument 1 is invalid
 template<typename _Ty,class = typename std::enable_if<std::is_base_of<OverVoid, remove_all_pointers<_Ty>::type>::value>::type>
                                                                                                                       ^
..\src\helllo_world.cpp: In function 'int main()':
..\src\helllo_world.cpp:31:14: error: template argument 2 is invalid
  Move<Meta***> z;
              ^
..\src\helllo_world.cpp:32:13: error: template argument 2 is invalid
  Move<Meta**> w;
             ^
..\src\helllo_world.cpp:33:12: error: template argument 2 is invalid
  Move<Meta*> x;
            ^
..\src\helllo_world.cpp:34:11: error: template argument 2 is invalid
  Move<Meta> y;
           ^
..\src\helllo_world.cpp:31:16: warning: unused variable 'z' [-Wunused-variable]
  Move<Meta***> z;
                ^
..\src\helllo_world.cpp:32:15: warning: unused variable 'w' [-Wunused-variable]
  Move<Meta**> w;
               ^
..\src\helllo_world.cpp:33:14: warning: unused variable 'x' [-Wunused-variable]
  Move<Meta*> x;
              ^
..\src\helllo_world.cpp:34:13: warning: unused variable 'y' [-Wunused-variable]
  Move<Meta> y;
             ^
Community
  • 1
  • 1
Wissam Y. Khalil
  • 133
  • 1
  • 5
  • 13
  • 2
    Please provide a complete minimal compilable example of what you want to do, and explain exactly what is not working here. As it stands, you only link to random questions without any explanation. I also doubt this has anything to do with TDM-MinGW, rather it is GCC that is better versed in the Standard. – rubenvb Jul 31 '15 at 07:56
  • 2
    You don't even show us the actual code. In the actual code, there's a `class=` before the `typename enable_if…` – Columbo Jul 31 '15 at 08:00
  • 4
    Compiler error is not a *crash*. – Jarod42 Jul 31 '15 at 08:04
  • added requested edits – Wissam Y. Khalil Jul 31 '15 at 09:51
  • What do you mea by "previously compiling"? What compiler? What changed? – rubenvb Jul 31 '15 at 09:57
  • it was compiling when i was using VisualStudio cl compiler for c++, but now I moved to TDM-GCC and it is no longer compiling – Wissam Y. Khalil Jul 31 '15 at 09:59
  • That's because it's illegal code, wrongfully accepted by the Visual C++ compiler. It seems to me that the cleaned up (ie added `typename` where necessary) version, http://coliru.stacked-crooked.com/a/4dbe771dadfce6d8, is redefining the `Move` class twice, removing the superfluous definitions makes it compile. Note how the repetitions of `Move` seem to be identical. – rubenvb Jul 31 '15 at 10:02
  • @rubenvb thanks :) add it as an answer so that other people in the community can see it and hence i can select it as the right answer :) – Wissam Y. Khalil Jul 31 '15 at 10:19
  • So the repeated code is in fact intended and there's no typo's lurking anywhere? – rubenvb Jul 31 '15 at 11:09

1 Answers1

1

You are missing some typenames and have the class template Move definition repeated three times.

Th below code works:

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T> class remove_all_pointers{
public:
    typedef T type;
};

template <typename T> class remove_all_pointers<T*>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* const>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* volatile>{
public:
    typedef typename remove_all_pointers<T>::type type;
};

template <typename T> class remove_all_pointers<T* const volatile >{
public:
    typedef typename remove_all_pointers<T>::type type;
};


class OverVoid{
public:

    static bool isOverVoid (){
    return true;
    }
    virtual ~OverVoid(){
    }
};

class Meta: public OverVoid{

};

class Physical{
public:

};

template<typename T, typename = typename std::enable_if<std::is_base_of<OverVoid, typename remove_all_pointers<T>::type>::value>::type>
class Move{
public:
    Move()
    {
        cout<<"### "<<remove_all_pointers<T>::type::isOverVoid()<<endl;
    }
};

/*
template<typename T,typename = typename std::enable_if<std::is_base_of<OverVoid, typename remove_all_pointers<T>::type>::value>::type>
class Move{
public:
    Move()
    {
        cout<<"### "<<remove_all_pointers<T>::type::isOverVoid()<<endl;
    }
};

template<typename T, typename = typename std::enable_if<std::is_base_of<OverVoid, typename remove_all_pointers<T>::type>::value>::type>
class Move{
public:
    Move()
    {
        cout<<"### "<<remove_all_pointers<T>::type::isOverVoid()<<endl;
    }
};
*/

int main(){
    Move<Meta***> z;
    Move<Meta**> w;
    Move<Meta*> x;
    Move<Meta> y;
}

Live demo here.

Community
  • 1
  • 1
rubenvb
  • 74,642
  • 33
  • 187
  • 332