3
votes

I am trying to use enable_if in boost to do template specialization, but cannot get it to work and confused as to how to write it and what the syntax actually means. I've read the boost docs but still doesn't quite make sense to me

I have four methods which i want all to be named the same thing and are all very similar. I have two functions that will return a string and two functions that will return an integer. In each case the parameter are int,int,return type or int,const char*,return type since the last parameter will be a default value that can be returned.

so something like this...

int getVal(int,int,int)
int getVal(int,const char*,int)
string getVal(int,int,string)
string getVal(int,const char*,string)

but this will not work since the parameters are the same and only the return type differs and i need it to be a templated method rather just an overloaded method. This is in a non-templated class. so i need to enable_if if the return type is a string or an int, or maybe check enable_if on the last parameter?

Any help would be appreciated, if someone would be able to explain what the syntax means and is actually doing that would be helpful as well. Thanks

this is one of the many attempts i tried in getting the correct syntax..

 template<typename myType> 
   typename enable_if<boost::is_arithmetic<myType>, myType>::type
    GetValue(int row, int col, myType d)
    { 
        unsigned int columnIndex = this->GetColumnIndex(col);

        try {
            CheckColumnType(col, Integer);
        }
        catch(DatatableException e){
            return d;
        }
        if("0" == this->m_rows[row][col])
        {
            return 0;
        }
        else if("1" == this->m_rows[row][col])
        {       
            return 1;
        }
        else
        {
            return atoi(this->m_rows[row][col].c_str());
        }
    }

template<typename myType> 
  typename disable_if<boost::is_arithmetic<myType>, myType>::type
   GetValue(int row, int col, myType d)
    {
        unsigned int columnIndex = this->GetColumnIndex(col);

        try {
            CheckColumnType(col, String);
        }
        catch(DatatableException e){            
            return d;

        }
        return this->m_rows[row][col];
    }

 template <class T>
  T GetValue(int row, typename enable_if<is_arithmetic<!T> >::type* dummy = 0){
{
            unsigned int columnIndex = this->GetColumnIndex(col);
            try {
                CheckColumnType(col, Integer);
            }
            catch(DatatableException e){
                return d;
            }
            if("0" == this->m_rows[row][col])
            {
                return 0;
            }
            else if("1" == this->m_rows[row][col])
            {       
                return 1;
            }
            else
            {
                return atoi(this->m_rows[row][col].c_str());
            }
    }

 template <class T>
    T GetValue(int row, typename enable_if<is_arithmetic<T> >::type* dummy = 0){

            try {
                CheckColumnType(col, Integer);
            }
            catch(DatatableException e){
                return d;
            }
            if("0" == this->m_rows[row][col])
            {
                return 0;
            }
            else if("1" == this->m_rows[row][col])
            {       
                return 1;
            }
            else
            {
                return atoi(this->m_rows[row][col].c_str());
            }
    }
1
I'm confused. Which functions are complaining about having the same argument types? I can see four functions with different argument types.Chowlett
It's not clear what is the actual problem. There shall be no problems with overloading your functions, they all have different arguments list - (int, int, int), (int, const char*, int), (int, int, string), (int, const char*, string)Rost
My requirement is to use a template function, and if i wanted to add other functions that take the same parameters but return a bool value or a date value, then there would be a problem.Bullsfan127
The problem is that default arguments make the calls ambiguous. For example, int ret = getVal(1,1); will not compile if the third parameter in each function has a default argument.cschwan
yes i know, that is why i'm trying to "enable" or "disable" the functions that will cause the call to be ambiguous based on the return type or one of the parametersBullsfan127

1 Answers

0
votes

I am not sure if std::enable_if is what you are looking for. Did you try to use function template specialization?

template <typename T>
T function(int number, T const& result = T());

template <>
std::string function(int number, std::string const& result)
{
        // implementation for T = std::string
        return result;
}

template <>
int function(int number, int const& result)
{
        // implementation for T = int
        return result;
}

Note that this requires C++11. The ambiguity from default arguments can be resolved by explicitly specifying the type, e.g. int ret = function<int>(1);.