Skip to content

Instantly share code, notes, and snippets.

@tomilov
Created October 6, 2015 05:53
Show Gist options
  • Save tomilov/bb46edaead9b414f43fc to your computer and use it in GitHub Desktop.
Save tomilov/bb46edaead9b414f43fc to your computer and use it in GitHub Desktop.
call qualified operator () of stateless global functor constructed on demand
#include <iostream>
#include <type_traits>
#include <utility>
#include <cstdlib>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
template< typename F >
F callee = {};
template< typename F >
auto call = [] (auto &&... args) -> decltype(auto) { return std::forward< F >(callee< std::decay_t< F > >)(std::forward< decltype(args) >(args)...); };
#pragma clang diagnostic pop
#define PP { std::cout << ++i << ' ' << __PRETTY_FUNCTION__ << std::endl; }
struct L
{
mutable int i = 0;
void operator () () const & { PP }
void operator () () & { PP }
void operator () () const && { PP }
void operator () () && { PP }
void operator () () volatile const & { PP }
void operator () () volatile & { PP }
void operator () () volatile const && { PP }
void operator () () volatile && { PP }
};
struct M
{
mutable int i = 0;
void operator () () const { PP }
void operator () () { PP }
void operator () () volatile const { PP }
void operator () () volatile { PP }
};
int
main()
{
{ auto const & c = call< L >; c(); }
{ auto const & c = call< L & >; c(); }
{ auto const & c = call< L && >; c(); }
{ auto const & c = call< L const >; c(); }
{ auto const & c = call< L const & >; c(); }
{ auto const & c = call< L const && >; c(); }
{ auto const & c = call< volatile L const >; c(); }
{ auto const & c = call< volatile L const & >; c(); }
{ auto const & c = call< volatile L const && >; c(); }
std::cout << std::endl;
{ auto const & c = call< M >; c(); }
{ auto const & c = call< M & >; c(); }
{ auto const & c = call< M && >; c(); }
{ auto const & c = call< M const >; c(); }
{ auto const & c = call< M const & >; c(); }
{ auto const & c = call< M const && >; c(); }
{ auto const & c = call< volatile M const >; c(); }
{ auto const & c = call< volatile M const & >; c(); }
{ auto const & c = call< volatile M const && >; c(); }
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment