
On 10/18/07, Doug Gregor <dgregor@osl.iu.edu> wrote:
On Oct 16, 2007, at 5:58 AM, Marco Costalba wrote:
Starting to hack with boost libraries I found myself more and more stumbling across a big brick of C++ language, i.e. SFINAE works on types only, not on expressions.
If an expression is ill formed there's no SFINAE around that will avoid you a barfing compiler.
This issue has been actively discussed in the C++ committee. You can track it's progress via core issue 339 on the Core Issues list, which is here:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#339
At the very bottom of the issue text, there is a note that describes the latest view on the matter. The resolution we're likely to get is that SFINAE will be extended to support expressions. There are still cases that will cause "hard" failures (not SFINAE failures), for example if one ends up trying to instantiate a class template inside a sizeof() expression and that instantiation fails.
From above cited document:
"We decided it's easier to write the definition by listing the errors that are not treated as SFINAE failures, and the list we came up with is as follows: 1-errors that occur while processing some entity external to the expression, e.g., an instantiation of a template or the generation of the definition of an implicitly-declared copy constructor" This limitation seems quite important. As example in the code I posted in this thread: template<int n, typename arg> void dispatch_on_value(std::string const& s, arg const& a) { if ( s == some_string(n) ) /* calls member foo() on the class returned by get_a_class */ return get_a_class<n>().foo(a); return dispatch_on_value<n-1>(s, a); // try with next one } I could think to use sizeof as a specialization somewhere to filter out invalid functions, something like: sizeof(get_a_class<n>().foo(arg())) But, if I have read correctly the proposed change, this would result in being still considered an error, not under SFINAE case. IMHO closing the doors to instantiation of a class template inside a sizeof() expression could cut away a good number of possible cases, also not easy to foressen ones (i.e. from where language 'progress' normally comes from). In my case, if you have a compile time set of functions/classes and you want to choose at run-time one among them using a run-time entity (variable, arguments values, etc..) a possible way would be to create at compile time a chain of all the instantations of your set, linked with recursion, then at run-time return from the recursion chain at the point your run-time requirements are met. But this works only if at compile-time it would be possible to discard the ill-formed ones when instantiating the recursive chain. Am I missing something? Thanks Marco