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

末鹿安然 提交于 2019-12-18 11:48:39

问题


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:

template<typename T, bool flag>
class base
{
   foov<std::enable_if<flag, T>::type> m_var;
};

the above code could not survive the compiler.

Does anyone know how I can achieve this?


回答1:


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.




回答2:


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



回答3:


#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




回答4:


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.



来源:https://stackoverflow.com/questions/25492589/can-i-use-sfinae-to-selectively-define-a-member-variable-in-a-template-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!