Is there a way to use SFINAE to determine if a call to a templated function would fail due to the types provided?

405 views Asked by At

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.

1

There are 1 answers

1
Vaughn Cato On

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.