Skip to content

Instantly share code, notes, and snippets.

@jacquelinekay
Last active April 13, 2016 19:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacquelinekay/ef45d875a9cfbcda1e85db27b296cf1b to your computer and use it in GitHub Desktop.
Save jacquelinekay/ef45d875a9cfbcda1e85db27b296cf1b to your computer and use it in GitHub Desktop.
Clang 3.4 SFINAE bug
#include <iostream>
#include <functional>
#include <memory>
#include <utility>
class TimerBase
{
};
using VoidCallbackType = std::function<void()>;
using TimerCallbackType = std::function<void(TimerBase &)>;
template<
typename FunctorT,
typename std::enable_if<
std::is_convertible<FunctorT, VoidCallbackType>::value ||
std::is_convertible<FunctorT, TimerCallbackType>::value
>::type * = nullptr
>
class GenericTimer : public TimerBase
{
public:
GenericTimer(FunctorT && callback)
: callback_(std::forward<FunctorT>(callback))
{
}
void
execute_callback()
{
execute_callback_delegate<>();
}
template<
typename CallbackT = FunctorT,
typename std::enable_if<
std::is_convertible<CallbackT, VoidCallbackType>::value
>::type * = nullptr
>
void
execute_callback_delegate()
{
callback_();
}
template<
typename CallbackT = FunctorT,
typename std::enable_if<
std::is_convertible<CallbackT, TimerCallbackType>::value
>::type * = nullptr
>
void
execute_callback_delegate()
{
callback_(*this);
}
protected:
FunctorT callback_;
};
class Factory
{
public:
template<typename CallbackType>
typename std::shared_ptr<GenericTimer<CallbackType>>
create_wall_timer(
CallbackType callback) {
return std::make_shared<GenericTimer<CallbackType>>(std::move(callback));
}
};
int main(int argc, char** argv) {
std::string foo = "foo";
auto callback = [&foo]() -> void
{
std::cout << foo << std::endl;
};
Factory f;
auto timer = f.create_wall_timer(callback);
timer->execute_callback();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment