Tag Archives: Wakely

Examples of SFINAE (by Jonathan Wakely at ACCU 2013)

I’m currently attending ACCU2013 at Bristol and saw Jonathan Wakely’s presentation on SFINAE (Substitution Failure Is Not An Error) this morning.

This is a traditional SFINAE example using type traits.  true_type and false_type just need to have different sizes, then we can use function template specialization to differentiate between two cases.

typedef char true_type;
typedef double false_type;
template<class T>
true_type is_iter( typename T::iterator_category* t );
template<class T>
false_type is_iter(...);
template<class T>
struct is_iterator
{
  static const bool value =
    (sizeof(is_iter<T>(0)) == sizeof(true_type));
};

void testTypeTrait()
{
 std::cout
    << "Try int " << is_iterator<int>::value << "\n";
    << "Try vector<int>::iterator "
    << is_iterator<std::vector<int>::iterator>::value << "\n";
}

This example later in the presentation really stood out – a step towards Concepts, it shows syntax available today for restricting the types that will compile with a given template (thanks to C++11 aliasing and default arguments for template parameters):

class WidgetBase
{};

class Widget : public WidgetBase
{};

class Bodget
{};

class Decorator
{
private:
template<class T>
using IsDerivedWidget = typename std::enable_if<
        std::is_base_of<WidgetBase, T>::value>::type;

public:
template<class T,
class Requires = IsDerivedWidget<T>>
Decorator( const T& )
{}
};

So if I instantiate Decorator with Widget, it compiles (because Widget derives from WidgetBase), but instantiating with Bodget yields a compiler error (because Bodget does not inherit from WidgetBase).

Widget w;
Decorator decoratedWidget( w );
Bodget b;
Decorator decoratedBodget( b ); // Error

This code all compiles with recent versions of gcc (e.g. 4.7).  Under Visual Studio, only the traditional example compiles (default arguments for function templates are not yet supported, neither is aliasing, not even with the Nov ’12 CTP).

1 Comment

Filed under C++ Code

C++11 noexcept

Someone on ISOCpp re-awakened an old question on StackOverflow about noexcept, dynamic v static checking and differences between noexcept and the (now deprecated) throw specifiers.

Throw specifiers were the subject of Item 14 – Use Exception Specifications Judiciously in Scott Meyers’ More Effective C++. The drawbacks he mentions are: the standard prohibits compilers from rejecting calls to functions that might violate the exception specification (including if there is no specifier on the called function – this to allow integration with legacy code libraries that lack such specifications); you cannot know anything about the exceptions thrown by a template’s type parameters – so templates and exception specifications don’t mix; they’re easy to violate inadvertently (e.g. via callback functions); they lead to abrupt program termination when violated.

Stroustrup wrote this about noexcept in his C++11 FAQ:

If a function declared noexcept throws (so that the exception tries to escape the noexcept function) the program is terminated (by a call to terminate()). The call of terminate() cannot rely on objects being in well-defined states (i.e. there is no guarantees that destructors have been invoked, no guaranteed stack unwinding, and no possibility for resuming the program as if no problem had been encountered). This is deliberate and makes noexcept a simple, crude, and very efficient mechanism

This post gives a history of noexcept,

If the noexcept feature appears to you incomplete, prepared in a rush, or in need of improvement, note that all C++ Committee members agree with you. The situation they faced was that a safety problem with throwing move operations was discovered in the last minute and it required a fast solution

There are however important differences [between noexcept and throw()]. In case the no-throw guarantee is violated, noexcept will work faster: it does not need to unwind the stack, and it can stop the unwinding at any moment (e.g., when reaching a catch-all-and-rethrow handler). It will not call std::unexpected. Next, noexcept can be used to express conditional no-throw, like this: noexcept(some-condition)), which is very useful in templates, or to express a may-throw: noexcept(false).

One other non-negligible difference is that noexcept has the potential to become statically checked in the future revisions of C++ standard, whereas throw() is deprecated and may vanish in the future.

and this comment on SO from Jonathan Wakely also makes sense:

template code such as containers can behave differntly based on the presence or absence of noexcept (and equivalently throw()) so it’s not just about compiler optimizations, but also impacts library design and choice of algorithm. The key to doing that is the noexcept operator that allows code to query how throwy an expression is, that’s the new thing, and all that cares about is a yes/no answer, it doesn’t care what type of exception might be thrown, only whether one might be thrown or not

Leave a comment

Filed under C++