Reputation: 1
I have a template function that's working fine if I don't use an enum
as argument type (here in condensed form; it transforms a string into anotjer type using stringstream
s):
template<typename T>
void section::getVal(std::string key,T& var)
{
std::stringstream ss; ss.str(key);
ss>>var;
}
Now I want that function to work with any enum
, so i tried
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);
}
}
Unfortunately this doesn't compile
(error: no match for 'operator>>' (operand types are 'std::stringstream {aka std::__cxx11::basic_stringstream<char>}' and 'sensact::slimit')
ss>>var;)
If I replace ss>>var;
with something that doesn't care for the type (int n=0;
) it compiles and the if-distinction/ is_enum
works perfectly and the else block is executed if var
is an enum
type.
So how can I get it to work and why does it not compile?
Upvotes: 0
Views: 196
Reputation: 60218
While an if
statement only executes one branch, it still compiles all the branches. Since the code is ill-formed in one of the branches, you get an error.
If you want to conditionally compile some branches, you can use constexpr if
like this:
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);
}
Thanks to @Jarod42 for the underlying_type
suggestion in the comment.
Upvotes: 3