How can I call every instantiated function of a template function? - c++

Is it somehow possible to call every instantiation of a template function without knowing what will get instantiated at write-code-time?
#include <iostream>
template<typename T>
void print_size_of()
{
std::cout << sizeof(T) << "\n";
}
int main()
{
print_size_of<int>();
print_size_of<double>();
//won't work but maybe it shows what i want to do:
template<typename T>
print_size_of<T>();
//is there a syntax so that the compiler replaces that with `print_size_of<int>(); print_size_of<double>();`
}

This is possible; you need to add some static variable inside the function template body to record those instantiations.
In the code below, every instantiated function will have a static variable, whose constructor will register the function pointer to a global registration center:
std::vector<void(*)()> funcs;
struct helper {
explicit helper(void (*f)()) { funcs.push_back(f); }
};
template<typename T>
void print_size_of()
{
static helper _(&print_size_of<T>);
std::cout << sizeof(T) << "\n";
}
int main()
{
print_size_of<int>();
print_size_of<double>();
std::cout << "All instantiation:\n";
for ( auto f : funcs ) {
f();
}
}
EDIT:
This is not strictly recording instantiation. It only records those being called before. If you instantiate it by other methods like taking its address:
void (*f)() = &print_size_of<short>;
but don't call it, then this function pointer won't be registered.
EDIT2:
In fact, it is possible to faithfully record all instantiations. The key point is to associate the instantiation of the function template to the instantiation of a class template. Then a static member of that class will be guaranteed to initialize before entering main() function.
// this one is to make sure `funcs` is initialized
auto &get_funcs() {
static std::vector<void(*)()> funcs;
return funcs;
}
template<void (*f)()>
struct helper {
helper() { get_funcs().push_back(f); }
// this is a static class member, whose initialization is before main()
static helper _ins;
};
template<void (*f)()> helper<f> helper<f>::_ins;
template<typename T>
void print_size_of()
{
// force instantiation of a class
const void *_ = &helper<&print_size_of<T>>::_ins;
std::cout << sizeof(T) << "\n";
}
int main()
{
print_size_of<int>();
print_size_of<double>();
void (*f)() = &print_size_of<short>;
std::cout << "All instantiation:\n";
for ( auto f : get_funcs() ) {
f();
}
}

No, that is not possible.
You can get close by calling every instantiation which was already called once (Use a static variable to register on first call), but that's the best you can do.

Related

using pointer to inline function vs using pointer to function

I want to pass pointers of some functions to a template class to use them later. I was wondering if:
Does it make a possibly (speed-wise) beneficial difference if I make these functions inline?
Functions themselves are possibly one line wrapper for another functions like the example below:
//inline ?
void func_wrapper_1(){
func1(arg1);
}
//inline ?
void func_wrapper_2(){
func2(arg2);
}
and the class template is like the example below:
template<void(*f1)(), void(*f2)()>
class caller{
public:
static void func(int v){
if(v) {
(*f1)();
}else{
(*f2)();
}
}
};
And later on in the main function it will be used like the example below:
caller<func_wrapper_1,func_wrapper_2>::func(0);
caller<func_wrapper_1,func_wrapper_2>::func(1);
I know that every things depends on compiler and compiling option, but lets assume compiler accepts to make these functions inline.
Whether or not a compiler will be smart enough to inline a given situation is up for grabs but I think it may be possible by creating Callable Types by overloading the function call operator.
Something like this:
template<typename Func1, typename Func2>
class caller{
public:
static void func(int v){
if(v) {
// Func1() - creates an object of type Func1
// that object is 'called' using the '()' operator
Func1()();
}else{
Func2()();
}
}
};
struct CallableType1
{
// overloading the function call operator makes objects of
// this type callable
void operator()() const { std::cout << "callable 1" << '\n'; }
};
struct CallableType2
{
void operator()() const { std::cout << "callable 2" << '\n'; }
};
int main()
{
caller<CallableType1, CallableType2> cc;
cc.func(2);
}

Can I get rid of this class member in this template?

I had a templated class that had a getter function and a setter function pointer. When I created an object of this class and I didn't want its setter to do anything I'd just pass nullptr as the setter function argument. Then at runtime, it would check if its setter pointer was nullptr to see whether it should call the setter.
Using a function pointer isn't good enough now because I want the class to be able to store a lambda. So instead of a function pointer the setter is now a template type argument. Before I used to pass a nullptr to signify that there was no setter, but now I can't, so I use a dummy char member, as you can see:
template <typename GetFunctionType, typename SetFunctionType = char>
class MyClass
{
public:
MyClass(GetFunctionType getFunction, SetFunctionType setFunction = char(0))
: getFunction(getFunction), setFunction(setFunction)
{}
GetFunctionType getFunction;
SetFunctionType setFunction;
typedef decltype(getFunction()) ReturnType;
void set(ReturnType value)
{
if constexpr (std::is_invocable_v<decltype(setFunction), ReturnType>)
{
setFunction(value);
std::cout << "Setter called\n";
}
else
{
// ELSE DO NOTHING
std::cout << "Object has no setter\n";
}
}
};
int main()
{
MyClass foo([]() { return 7; }, [](int val) { std::cout << "You have set the value\n"; });
MyClass foo2([]() {return 7; }); // THIS OBJECT HAS NO SETTER, BUT HAS A CHAR
// MEMBER THAT I USED AS A DUMMY
foo.set(1);
foo2.set(1);
}
My question is do I need that dummy char in cases where the object has no setter function?
Using a function pointer isn't good enough now because I want the
class to be able to store a lambda!
Not completely true!
You could store the capture-less lambdas to the typed-function pointers.
See [expr.prim.lambda.closure] (sec 7)
The closure type for a non-generic lambda-expression with no
lambda-capture whose constraints (if any) are satisfied has a
conversion function to pointer to function with C++ language linkage
having the same parameter and return types as the closure type's
function call operator.
In addition to that, normally a getter would have a signature
ReturnType /*const-ref*/ <function>();
similarly, the setter would have
void <function>(ArgumentType) /*const*/; // where ReturnType == ArgumentType usually
Combining these two information, I am suggesting the following re-structuring of your class.
(See live demo online)
#include <iostream>
#include <string>
template <typename ArgType>
class MyClass final
{
// alias types
using GetFunctionType = ArgType(*)(void);
using SetFunctionType = void(*)(ArgType);
GetFunctionType getFunction;
SetFunctionType setFunction;
public:
// Now you can set the function pointer to by default `nullptr`
MyClass(GetFunctionType getFunction = nullptr, SetFunctionType setFunction = nullptr)
: getFunction{getFunction}
, setFunction{setFunction}
{}
void set(ArgType value) const noexcept
{
if (getFunction && setFunction) // runtime nullptr check
{
setFunction(value);
std::cout << "Setter called\n\n\n";
} else {
std::cout << "Object has no setter\n\n";
}
}
};
int main()
{
// mention the argument type
MyClass<int> foo(
[]() { return 7; },
[](int val) { std::cout << "You have set the value: " << val << "\n"; }
);
MyClass<std::string> foo2([]() {return std::string{}; }); // also works
foo.set(1);
foo2.set("String");
}
It would be good if there was a way you could pass void or 'something'
so that when you declare a class member like this: T setFunction; the
compiler just removes it from the class.
To my understanding, when you do the partial specialization, you do not even need to declare the setFunctionat all.
Following is the example code, in which the first specialization
template <typename Getter, typename Setter>
class MyClass final{};
handles the when you provide Getter and Setter cases, whereas the second one handles the no setter situation.
template <typename Getter>
class MyClass<Getter, std::nullptr_t> final
Unfortunately, you still need to specify the second argument (i.e. std::nullptr_t{}) in order to choose the correct specialization.
(See live demo online)
#include <iostream>
#include <cstddef> // std::nullptr_t
template <typename Getter, typename Setter>
class MyClass final
{
Getter mGetFunction;
Setter mSetFunction;
using ReType = decltype(mGetFunction());
static_assert(std::is_invocable_v<decltype(mGetFunction)>, " Getter is not callable!");
static_assert(std::is_invocable_v<decltype(mSetFunction), ReType>, " Setter is not callable!");
public:
MyClass(Getter mGetFunction, Setter mSetFunction) noexcept
: mGetFunction{ mGetFunction }
, mSetFunction{ mSetFunction }
{}
void set(ReType value) const noexcept {
mSetFunction(value);
std::cout << "Setter called\n";
}
};
template <typename Getter>
class MyClass<Getter, std::nullptr_t> final
{
Getter mGetFunction;
using ReType = decltype(mGetFunction());
static_assert(std::is_invocable_v<decltype(mGetFunction)>, " Getter is not callable!");
public:
MyClass(Getter mGetFunction, std::nullptr_t) noexcept
: mGetFunction{ mGetFunction }
{}
void set(ReType value) const noexcept {
std::cout << "Object has no setter\n";
}
};
int main()
{
MyClass foo{
[]() { return 7; },
[](int val) { std::cout << "You have set the value\n"; }
};
foo.set(1);
//unfortunately, needed to pass second argument for class instantiation
MyClass foo2([]() {return 7; }, std::nullptr_t{});
foo2.set(1);
}

passing lambda to a lambda callback parameter

I am using c++14 and I have a use case where I have to effectively do this:
template <typename F>
void foo (F&& fun)
{
auto l = []()->int
{
return 20;
};
fun(l);
}
int main ()
{
auto l = [] (auto& a)
{
std::cout << "Hello function: " << a() << std::endl;
// 'a' has to be copied to a queue optionally
};
foo(l);
}
But the foo() in-turn calls a million function - which uses the callback 'fun'. I cannot put all the code in header file. The simplest way to keep the definition of foo() and the called functions in dot cpp file might be to change foo() to
void foo (std::function< void(std::function<int(void)>) > fun)
But this is too inefficient, I dont want any memory allocation. Here there will be many, one of the creating the 'fun' and then for every call to 'fun(...)'. Now the outer std::function can be optimized by using something like the function_ref mentioned here.
https://vittorioromeo.info/index/blog/passing_functions_to_functions.html#fn_view_impl
But inner std::function, cannot be because it has to be 'optionally' copied to a queue. Now how can I make this work without a memory allocation - as close to the performance as using the template. [ One way is to have something like the std::function with a fixed internal storage.] But I have a feeling there exists a way by throwing more templates to achieve what I want. Or some way to change the interface to have more of less same effect.
Not sure if this is what you're looking for, but maybe it can be to some help.
#include <iostream>
#include <deque>
#include <memory>
struct lambdaHolderBase {
virtual int operator()() = 0;
};
template <typename T>
struct lambdaHolder : lambdaHolderBase {
lambdaHolder(T tf) : t(tf) {}
T& t;
int operator()() override { return t(); }
};
template <typename F>
void foo (F&& fun)
{
auto l = []()->int
{
return 20;
};
lambdaHolder<decltype(l)> l2(l);
fun(l2);
}
int main ()
{
auto l = [] (auto& a)
{
static std::deque<lambdaHolderBase*> queue;
std::cout << "Hello function: " << a() << std::endl;
queue.emplace_back( &a );
// 'a' has to be copied to a queue optionally
};
foo(l);
}

Create functions in preproccesor in C++

I'm using a timer library in Arduino IDE that has a function which takes "void(*func)(void)" as a parameter and runs it after certain time.I need to pass a function in my code with that library, the problem is I need "n" functions that do the same thing (just the variables involved inside the function take different values, which I take from an array of struct), that's why I can't use only one function and I need to be able to compile different functions with identical syntax but different variables involved.
I don't know how I can resolve this, what I want to do is to be able to create functions like in a for loop,
for(int i=0;i<MAX_FUNC;i++)
{
void func[i](){
x= structuredata.x[i];
}
}
I know this syntax is completely wrong but I'd like to know how can I achieve something like this . I tried using classes instead, but the library didn't let me use void functions created in a class as parameters, it indicated "unresolved overloaded function type"
If you're into template overrides and can restructure your functions as such, a solution to packing up a stack of callbacks to be fired consecutively is closer than you may think. You can make this more generic if the consistency of the function is literally identical. I.e. you can do this instead:
#include <iostream>
int ar[5] = { 1,2,3,4,5 };
// your function here
template <int i>
void callback()
{
// your code here. i is provided
int x = ar[i];
std::cout << "Got Value: " << x << '\n';
};
////////////////////////////////////////////////////////////
// unraveller
template<int N>
void callback_set()
{
callback_set<N-1>();
callback<N-1>();
}
// base callback set
template<>
void callback_set<0>() {}
////////////////////////////////////////////////////////////
int main()
{
callback_set<3>();
return 0;
}
Output
Got Value: 1
Got Value: 2
Got Value: 3
You "register" callback_set<N> as your callback, and it will chain up the calls to your function(s) for you. If individualized access to different implementations is needed, you can still to that, using full specializations:
#include <iostream>
// prototypes
template <int i>
void callback() {};
// your functions here
template<>
void callback<0>()
{
std::cout << "Callback #0" << '\n';
}
template<>
void callback<1>()
{
std::cout << "Callback #1" << '\n';
}
template<>
void callback<2>()
{
std::cout << "Callback #2" << '\n';
}
////////////////////////////////////////////////////////////
// unraveller
template<int N>
void callback_set()
{
callback_set<N-1>();
callback<N-1>();
}
// base callback set
template<>
void callback_set<0>() {}
////////////////////////////////////////////////////////////
int main()
{
callback_set<3>();
return 0;
}
Output
Callback #0
Callback #1
Callback #2
In essence you style-up your registered callback using callback_set<N> where N is the number of callbacks you've provided overrides for. Just a thought, but seems like it would be a fairly elegant solution to your problem if I understand it correctly.
You need some metaprogramming for that...
const int MAX_FUNC = 1000;
typedef void (*Tcallback)();
struct Tdata
{
int whatever;
};
Tdata callbackData[MAX_FUNC];
Tcallback callbacks[MAX_FUNC];
template <int index>
void callbackToIndex()
{
// callback knows it's index and thus can access some global structure for it's data
printf("%u", index);
callbackData[index];
}
template <int index>
void callbackCreate()
{
callbacks[index] = &callbackToIndex<index>;
callbackCreate<index - 1>();
}
template <>
void callbackCreate<-1>()
{
}
void create()
{
callbackCreate<MAX_FUNC - 1>();
}

c++ functor and function templates

consider this simple and pointless code.
#include <iostream>
struct A {
template<int N>
void test() {
std::cout << N << std::endl;
}
};
int main() {
A a;
a.test<1>();
}
It is a very simple example of a function template. What if however, I wanted to replace A::test with an overloaded operator() to make it a functor?
#include <iostream>
struct A {
template<int N>
void operator()() {
std::cout << N << std::endl;
}
};
int main() {
A a;
a<1>(); // <-- error, how do I do this?
}
Certainly if the operator() took parameters which were dependent on the template, the compiler could possibly deduce the template. But I just can't figure out the proper syntax to specify template parameters with a parameterless functor.
Is there a proper way to do this?
Obviously, this code would work since it bypasses the functor syntax:
a.operator()<1>();
but that kinda defeats the purpose of it being a functor :-P.
You can only call
a.operator()<1>();
but that would not be using a functor. Functors need a non template operator(), as they must be able to be called as varname() and that won't work with your code.
To make it a real functor change your code a template class (functors are classes):
#include <iostream>
template<int N>
struct A {
void operator()() {
std::cout << N << std::endl;
}
};
int main() {
A<1> a;
a();
}
There's not another "direct" way I know other than the:
a.operator()<1>();
syntax. If you're open to changing the code, moving the template parameter to the class would work, or using a (boost|tr1)::bind to make a (boost|tr1)::function object.
You are trying to pass a template parameter to an instance of an object, which as far as I know is not allowed. You can only pass templates parameters to template functions or template objects.
a.test<1>(); and a.operator()<1>(); work because they are serving as template functions.
Use boost::bind (check out boost libraries) to fix it though.
struct A {
void operator()(int n) {
std::cout << n << std::endl;
}
};
int main(int argc, char* argv[]) {
A a;
boost::function<void()> f = boost::bind<void>(a, 1);
f(); // prints 1
return 0;
}
And you don't even have to mess with templates!
You're stuck. Have you considered something like
struct A {
template<int N>
struct B
{
void operator()()
{ std::cout << N << std::endl; }
};
template<int N>
B<N> functor() {return B<N>();}
};
int main()
{
A a;
a.functor<1>()();
}
Nope, there's no way around it. Like you said, you have to either call the operator explicitly (which defeats the purpose), or the template arguments must be able to be deduced by the compiler.