I have a templated class that I am using to provide a method that will use boost::lexical_cast
to cast its std::string
parameters to the type specified in the template, only if the lexical cast is possible. Currently to check if it's possible I'm simply checking to see if operator>>
is defined for the type in question. Here is a contrived example that basically illustrates what I'm doing:
template <typename ArgType, class Enable = void>
MyHelperClass
{
void Foo (ArgType arg&, std::string strArg) { } // not castable; do nothing
};
template <typename ArgType>
MyHelperClass<ArgType, boost::enable_if<boost::has_right_shift<std::istream, ArgType> >::type>
{
void Foo (ArgType arg&, std::string strArg) {
arg = boost::lexical_cast<ArgType>(strArg); // cast string arg to ArgType
}
};
So far this works fine for my code: all of the types that would fail a lexical cast end up with the first version and all others end up with the second, at least for the types my code is using this on. What I'm worried about is that I'm basically making the assumption that as long as the target type is InputStreamable then lexical_cast will not fail. The boost documentation for lexical_cast outlines some other requirements, which I should probably be checking as well but rather than creating a complex enable-if
and use mpl::and_
to string together a bunch of these conditions, I was wondering: is there a way to use SFINAE to just test directly whether that call to lexical_cast
would fail for the types given, and match the specialized template only if it wouldn't fail?
I've only ever seen examples for testing the existence of a function or operator, but never to test if a call to a templated function with a given type would produce an error.
I'm afraid not. Because lexical_cast is defined for all T, SFINAE won't help you. The fact that the body of lexical_cast() will fail to compile for certain types does not cause a substitution failure. The best you can do is to try to predict the conditions that will cause the body to fail, as you have already been doing.