can I use SFINAE to selectively define a member variable in a template class?

后端 未结 4 1673
不知归路
不知归路 2020-12-28 18:43

So what I want to do is to create a template class which may or may not contain a member variable based on the template argument passed in. like following:

t         


        
相关标签:
4条回答
  • 2020-12-28 19:06

    I have a workaround for this. Probably looks ugly but does resolve some of my issues

    First I define a type with zero size:

    typedef int zero[0];
    

    Next I create a macro:

    #ifndef VAR
    
    #define VAR(Enable,YourType,VarName) \    
    
    std::conditional< Enable,YourType,zero >::type VarName
    
    #endif
    

    Then a class like this:

    template < int Cond >
    class Foo
    {
        VAR(Cond == 0,int,var);
    
        void print()
        {
            if (!sizeof(var)) return;
            //...
        }
    };
    

    When you are using a result like var, check the size of it before using it. If the size is zero, it is invalid.

    0 讨论(0)
  • 2020-12-28 19:21

    Have a base class with enabled/disabled members based on template parameters:

    template<typename T, typename Enable = void>
    class base_class;
    
    // my favourite type :D
    template<typename T>
    class base_class<T, std::enable_if_t<std::is_same<T, myFavouriteType>::value>>{
        public:
            int some_variable;
    };
    
    // not my favourite type :(
    template<typename T>
    class base_class<T, std::enable_if_t<!std::is_same<T, myFavouriteType>::value>>{
        public:
            // no variable
    };
    
    template<typename T>
    class derived_class: public base_class<T>{
        public:
            // do stuff
    };
    

    This should give you a nice way to enable/disable members based on type.

    0 讨论(0)
  • 2020-12-28 19:22
    #pragma once
    #include <type_traits>
    
    template <typename T, bool D, typename Enabled=void>
    class Node;
    
    
    template <typename T, bool D>
    class Node<T, D, std::enable_if_t<D>>
    {
    public:
        Node(const T& v) : value(v) {}
    
    private:
        T value;
        Node* next = nullptr;
    };
    
    template <typename T, bool D>
    class Node<T, D, std::enable_if_t<!D>>
    {
    public:
        Node(const T& v) : value(v) {}
    
    private:
        T value;
        Node* next = nullptr;
        Node* prev = nullptr;
    };
    

    Single or double linked list node based on boolean flag

    0 讨论(0)
  • 2020-12-28 19:30

    I think this is what you are looking for.

    The class template does not have any member data by default.

    template<typename T, bool flag>
    class base
    {
    };
    

    Add a specialization of the class template that has the member data.

    template<typename T>
    class base<T, true>
    {
       foov<T> m_var;
    };
    
    0 讨论(0)
提交回复
热议问题