首页 > 解决方案 > is_enum<> 在另一个模板函数中不起作用/编译

问题描述

如果我不使用enumas 参数类型,我有一个工作正常的模板函数(这里是压缩形式;它使用 s 将字符串转换为 anotjer 类型stringstream):

template<typename T>
void section::getVal(std::string key,T& var)
{   
    std::stringstream ss; ss.str(key);
    ss>>var;
}

现在我希望该功能可以与 any 一起使用enum,所以我尝试了

enum slimit {lower,higher,between,nolim};

template<typename T>
void section::getVal(std::string key,T& var)
{   
    std::stringstream ss; 
    ss.str(key);
    if(!std::is_enum<T>::value)
        ss>>var;
    else
    {  
        int h;
        ss>>h;
        var=static_cast<T>(h);
    }
}

不幸的是,这不能编译

(error: no match for 'operator>>' (operand types are 'std::stringstream {aka std::__cxx11::basic_stringstream<char>}' and 'sensact::slimit')
                ss>>var;)

如果我用ss>>var;不关心类型 ( int n=0;) 的东西替换它,它会编译并且 if-distinction/工作得很好,如果是类型,is_enum则执行 else 块。varenum

那么我怎样才能让它工作,为什么它不能编译呢?

标签: c++templatesenums

解决方案


虽然一条if语句只执行一个分支,但它仍然编译所有分支。由于其中一个分支中的代码格式不正确,因此您会收到错误消息。

如果你想有条件地编译一些分支,你可以constexpr if这样使用:

if constexpr (!std::is_enum<T>::value)
   ss >> var;
else
{  
  int h;   // in general, std::underlying_type_t<T> instead of int,
           // to allow for other enumeration types
  ss >> h;
  var=static_cast<T>(h);
}

感谢@Jarod42underlying_type在评论中的建议。


推荐阅读