【问题标题】:How to use enable_if and template specialization c++?如何使用 enable_if 和模板专业化 c++?
【发布时间】:2012-10-17 13:01:14
【问题描述】:

我正在尝试在 boost 中使用 enable_if 来进行模板专业化,但无法让它工作并且对如何编写它以及语法的实际含义感到困惑。我已经阅读了 boost 文档,但对我来说仍然不太有意义

我有四种方法,我希望它们都被命名为相同的东西并且都非常相似。我有两个返回字符串的函数和两个返回整数的函数。 在每种情况下,参数都是 int,int,return 类型或 int,const char*,return 类型,因为最后一个参数将是可以返回的默认值。

像这样的……

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

但这不起作用,因为参数是相同的,只有返回类型不同,我需要它是一个模板化的方法,而不是一个重载的方法。这是在一个非模板类中。所以如果返回类型是字符串或整数,我需要 enable_if,或者检查最后一个参数的 enable_if?

如果有人能够解释语法的含义并且实际上正在这样做,那么任何帮助都会有所帮助。谢谢

这是我尝试获取正确语法的众多尝试之一。

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

【问题讨论】:

  • 我很困惑。哪些函数抱怨具有相同的参数类型?我可以看到四个具有不同参数类型的函数。
  • 不清楚实际问题是什么。重载你的函数应该没有问题,它们都有不同的参数列表 - (int, int, int)(int, const char*, int)(int, int, string)(int, const char*, string)
  • 我的要求是使用模板函数,如果我想添加其他接受相同参数但返回布尔值或日期值的函数,那就有问题了。
  • 问题是默认参数使调用不明确。例如,int ret = getVal(1,1); 将不会编译 如果每个函数中的第三个参数都有默认参数。
  • 是的,我知道,这就是为什么我试图根据返回类型或参数之一“启用”或“禁用”会导致调用不明确的函数

标签: c++ templates template-specialization


【解决方案1】:

我不确定std::enable_if 是否是您要查找的内容。您是否尝试过使用函数模板专业化?

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

请注意,这需要 C++11。默认参数的歧义可以通过显式指定类型来解决,例如int ret = function&lt;int&gt;(1);.

【讨论】:

  • 错误的解决方案。如果例如,它将不会以这种方式编译。您在第二个 if 中使用了一些特定于字符串的表达式。
  • 我改变了我的例子。现在应该可以编译了。
  • 在上面的例子中,没有任何理由将function声明为函数模板。
  • 这会起作用,但它只是重载了函数,而不是像我需要使用的那样使用模板。您的解决方案的模板部分并没有真正发挥作用吗?
  • 模板 仍然对函数没有影响,并且由于这不是模板类,它不会以任何方式工作,如果我尝试在函数中使用它们,类型名将是未定义的
猜你喜欢
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多