编译时间限制模板而不使用boost

时间:2015-07-31 07:51:43

标签: c++ templates c++11 typetraits tdm-mingw

这与这两个问题有关:

  1. standard c++11 way to remove all pointers of a type
  2. Compile Time Template restriction C++
  3. 第二个是我的

    问题是当我转移到TDM-GCC 64时,以下代码(以前正在工作)无法编译我确保启用了c ++ 11。

    我从第一个问题中取出了remove_all_pointers,并将其与我的问题(子弹#2)的答案结合起来。

    以下是我(之前)可编辑的例子

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

    它显示以下错误

    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;
                 ^
    

1 个答案:

答案 0 :(得分:1)

您是missing some typenames并且重复了三次类模板Move

以下代码有效:

#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