📜 ⬆️ ⬇️

Instantiation of function templates by type list (Part 2)

In the first part, we discussed how to achieve the transfer of the definition of the function template from the header file to the source code if the set of types for which the template is to be instantiated is known in advance. In this part we will see how to achieve this beautifully.

First of all, I will have to do what I planned to do closer to the end, but judging by the comments from the first part, this needs to be done urgently. Namely, no more lists of types on Alexandrescu. Now only templates with a variable number of parameters, or variadics, among the people:
template <typename... Types> struct TypeList{}; //       typedef TypeList<int, double, bool, char, const char*> MyTypeList; //        

Let us return to the last result from the first part and rewrite it in the manner of variadics:
 template<typename T> struct SomethingDoer { static void doSomething() { } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static void doSomething() { volatile MemFuncType x = &MyClass::f; (void)(x); SomethingDoer<TypeList<Tail...>>::doSomething(); } }; template <typename TList> struct Instantiator { Instantiator() { SomethingDoer<TList>::doSomething(); } }; Instantiator<MyTypeList> a; 

Now let's think about how to improve this solution. Improvement is necessary in two directions: generalization and disposal of trash.
With the second task, it seems easier to understand. The entire Instantiator class is designed to make the call:
  SomethingDoer::doSomething();. ,      : 
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
SomethingDoer::doSomething();. , :
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
  SomethingDoer::doSomething();. ,      : 
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
SomethingDoer::doSomething();. , :
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
  SomethingDoer::doSomething();. ,      : 
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
SomethingDoer::doSomething();. , :
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
  SomethingDoer::doSomething();. ,      : 
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
SomethingDoer::doSomething();. , :
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
  SomethingDoer::doSomething();. ,      : 
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
SomethingDoer::doSomething();. , :
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
  SomethingDoer::doSomething();. ,      : 
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...
SomethingDoer::doSomething();. , :
template<typename T> struct SomethingDoer { static int doSomething() // doSomething , , . { return 0; } }; template<typename Head, typename... Tail> struct SomethingDoer<TypeList<Head, Tail...>> { typedef void (MyClass::*MemFuncType)(Head); static int doSomething() { volatile MemFuncType x = &MyClass::f; (***) (void)(x); return SomethingDoer<TypeList<Tail...>>::doSomething(); } }; int a = SomethingDoer<MyTypeList>::doSomething(); // , , .

, . (***). .
, . , (***) - . ., MyClass::f - ,
template<typename T> struct FuncWrapper_MyClass_f { typedef decltype(&MyClass::f<T>) type; static constexpr type value = &MyClass::f<T>; }; , doSomething MyClass , f() .
( SomethingDoer Instantiator , doSomething() - instantiate() ).
template<typename Head, typename... Tail> // , struct Instantiator<TypeList<Head, Tail...>> // , { typedef Instantiator<TypeList<Tail...> > TailInstantiator; // static std::pair<typename FuncWrapper_MyClass_f<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapper_MyClass_f<Head>::value; // , return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); // . } };
- , . FuncWrapper_MyClass_f - . , instantiate() - FuncWrapper_MyClass_f::value FuncWrapper_MyClass_f::type . :
template<template<typename>class FuncWrapperType, typename Type> // - FuncWrapper_MyClass_f struct Instantiator { static int instantiate(...) { return 0; } }; template<template<typename>class FuncWrapperType, typename Head, typename... Tail> struct Instantiator<FuncWrapperType, TypeList<Head, Tail...> > { typedef Instantiator<FuncWrapperType, TypeList<Tail...> > TailInstantiator; static typename std::pair<typename FuncWrapperType<Head>::type, decltype(TailInstantiator::instantiate())> instantiate() { auto headTypeInstantiate = FuncWrapperType<Head>::value; return std::make_pair(headTypeInstantiate, TailInstantiator::instantiate()); } }; auto a = Instantiator<FuncWrapper_MyClass_f, MyTypeList>::instantiate(); // , , FuncWrapper_MyClass_f instantiate(), .
. , . struct Instantiator myclass.cpp . MyClass.cpp - FuncWrapper_MyClass_f . , , .
define InstantiateMemFunc(className, funcName, types) \ template<typename T> \ struct FuncWrapper_##className_##funcName \ { \ typedef decltype(&className::funcName<T>) type; \ static constexpr type value = &className::funcName<T>; \ }; \ volatile auto i_##className_##funcName = detail::Instantiator<FuncWrapper_##className_##funcName, types>::instantiate();
. MyClass.cpp :
namespace { InstantiateMemFunc(MyClass, f, MyTypeList) }
. , , .

. , . , , - . - , - . , , , , , -, - . , ++ , , ...

')

Source: https://habr.com/ru/post/235887/


All Articles