using pointer to inline function vs using pointer to function - c++

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);
}

Related

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);
}

How can I call every instantiated function of a template function?

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.

When is a reference to function useful?

A reference to array parameter is useful because it prevents decay, allowing you to deduce the size of an array.
template <typename T, std::size_t N>
constexpr std::size_t array_size(T (&) [N]) noexcept
{
return N;
}
But when is this useful?
template<typename T>
void foo(T& t)
{
// we now have a reference to bar
}
void bar() { }
int main()
{
foo(bar);
}
When do we care about preventing function to pointer decay? I'm asking about when this is useful, not why it isn't disallowed.
Like with objects, we us a pointer if “no object” (“no function”) is a sensible value and a reference if we wish to make sure that (unless somebody insists to shoot himself in the foot) there is always a valid object (function) referred to.
Consider the following poor man's function wrapper (wealthy man goes over there).
template<typename>
class Function; // never defined
template<typename ReturnT, typename... ArgT>
class Function<ReturnT(ArgT...)>
{
private:
ReturnT (*func_)(ArgT...);
public:
// Will also accept a 'nullptr'
Function(ReturnT (*func)(ArgT...)) noexcept : func_ {func}
{
}
ReturnT
operator()(ArgT... args)
{
return this->func_(args...);
}
};
Now we can write the following program, which works just fine.
#include <iostream>
int
add(int a, int b)
{
return a + b;
}
int
main()
{
Function<int(int, int)> f {add}; // ok
std::cout << f(5, 7) << std::endl; // ok, prints 12
}
However, we can also write the following program, which doesn't work so nice.
int
main()
{
Function<int(int, int)> f {nullptr}; // compiles fine
std::cout << f(5, 7) << std::endl; // compiles fine, crashes at run-time
}
Instead, if we had replaced the (*func) with (&func) in the template's definition,
// Won't accept a 'nullptr'
Function(ReturnT (&func)(ArgT...)) noexcept : func_ {func}
{
}
the line
Function<int(int, int)> f {nullptr}; // compile-time error
would have triggered a compile-time error.
To me the difference is like between normal variable reference and a pointer. References are nicer to deal with than pointers.
I had a use-case when I to customize a parts of an algorithm. It had some phases and I could switch between several options for each phase. This is of course achievable with pointers, but hey, you can use pointers instead of references pretty much everywhere too.
It looked similar to this:
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(void(&t)()) : barish(t) { };
void fun() {barish();};
private:
void(&barish)();
};
void bar() { cout << "meow\n";}
void bark() { cout << "woof\n";}
int main()
{
Foo foo1(bar);
Foo foo2(bark);
foo1.fun();
foo2.fun();
}
You can customize fun and don't have to deal with dereferencing and asserts that it's not null.

Static polymorphism in C++

#include <iostream>
template<typename Impl>
struct renderer{
void get(){
static_cast<Impl*>(this)->get();
}
};
struct open_gl : public renderer<open_gl>{
void get(){
std::cout << "OpenGL" << std::endl;
}
};
struct direct_draw : public renderer<direct_draw>{
void get(){
std::cout << "DX" << std::endl;
}
};
template<typename T>
void print_renderer(renderer<T> r){
r.get();
}
int main() {
auto gl = open_gl();
auto dx = direct_draw();
print_renderer(gl);
print_renderer(dx);
}
Why can't I change the parameter of print_renderer to void
print_renderer(const renderer<T> &r)?
cannot convert 'this' pointer from 'const renderer<open_gl>' to 'renderer<open_gl> &'
`
Why do I get a runtime error when I rename the method get in open_gl from
get to get1? Shouldn't this trigger a compiler error? Error = Stack overflow
**Note I am using the latest MSVC
1) Because get is not a const member function : it cannot make the promise of not modify your (const) argument.
You could declare get as const, and it compiles fine :
void get() const { ... }
2) The base get method will be called, going into infinite recursion : Stack Overflow.
If you declare your function override (it needs to be virtual), the compiler will throw an error if it does not indeed override a base method :
void get1() override { ... } // Compiler error
void get() override { ... } // Ok
Note:
The title is "Static polymorphism in C++", but I think that you misunderstood what is static polymorphism : it does not (have to) make use of inheritance (as you did). Rather, the templates compile-time duck typing will statically "resolve" function calls for you.
That is, you don't need related types, you don't need the base renderer class at all, and you can simply do the following (in which case, renaming to get1 will cause a compiler error) :
#include <iostream>
struct open_gl {
void get(){
std::cout << "OpenGL" << std::endl;
}
};
struct direct_draw {
void get(){
std::cout << "DX" << std::endl;
}
};
template<typename T>
void print_renderer(T r){
r.get();
}
int main() {
auto gl = open_gl();
auto dx = direct_draw();
print_renderer(gl);
print_renderer(dx);
}
Live demo
Becuase get is not marked const.
Because the base class method is used (irrelevantly of cast), and it goes into infinite loop.

C++ function pointer

Is there a way in C++ to make an "untyed" function pointer ?
For example:
// pointer to global function
void foo( void (*fptr)() );
// pointer to member
void foo( void (Bar::*fptr)() );
Is there a way I can remove the class on which the member is ? So that I could do something like this:
void foo( void ("any type"::*fptr)(), "same type as for the pointer" &instance );
And then, in foo, I would like to store that pointer in a list, so that I can iterator over the list and call the function/member pointed to, regardless of what class it belongs to. Of course I'd need a list of instances on which to call the function.
Thx.
You can use a template.
template<typename T> void foo( void(T::*)(), T&) { ... }
However, people prefer to go for the function object approach. You can do this dynamically or statically.
void foo(std::function<void()> func) {
// std::bind is used to make this out of a member function
}
template<typename T> void foo(T t = T()) {
t(); // This is the best approach.
}
Edit: Some examples.
void foo(std::function<void()> func) {
std::cout << "In example one ";
func();
}
template<typename T> void foo(T t = T()) {
std::cout << "In example two ";
t();
}
class some_class {
public:
void func() { std::cout << "in ur function!\n"; }
};
int main(void)
{
some_class* ptr = NULL;
struct tempfunctor {
tempfunctor(some_class* newptr)
: ptr(newptr) {}
some_class* ptr;
void operator()() { return ptr->func(); }
};
foo(tempfunctor(ptr)); // Calls example two
foo(std::function<void()>(tempfunctor(ptr))); // Calls example one
foo(std::function<void()>(std::bind(&some_class::func, ptr)); // I'm not that familiar with bind, it looks something similar to this.
std::cin.get();
}
This is the idiom called the function object idiom, used heavily in STL and other high-quality libraries. The compile-time template is cleaner but the std::function can be bound at runtime.
Edit # OP: I didn't quite see your list requirement in there. A std::function<void()> is your best choice here.
The following seems to work fine with g++ and MSVC:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace std;
void foo( boost::function<int()> f )
{
cout << "f() = " << f() << endl;
}
template< class Type >
void foo( int (Type::*f)() const, Type const& o )
{
foo( boost::bind( f, boost::ref( o ) ) );
}
int func1() { return 1; }
struct S { int func2() const { return 2; } };
int main()
{
foo( func1 );
foo( &S::func2, S() );
}
Disclaimer: I seldom use the Boost stuff and I just typed the above without bothering to check the docs, so possibly it could be expressed more cleanly.
Also note that C++0x standard library offers the same functionality.
Cheers & hth.,
No. The bound class is an intrinsic part of the member function pointer type.
You can, however, use a member function pointer to a common baseclass, or a template.
Can you use functors in your list?
http://en.wikipedia.org/wiki/Function_object
Have a look at Fast Delegates: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
This is an easy drop-in library that allows you to delegate pretty much anything and at a very high speed.
template <typename T>
void foo( void (T::*fptr)(), T& instance)
{
// ...
}
I'm not going to play expert here, but I think this will work, if not I would like to know why.
You can't have a pointer like that, but you could have a collection of boost::any, and put heterogeneous pointers (or any kind of functors) into it.
You can't do that, and you shouldn't do that even if you could, because it is against the spirit of the language. Create a base class with "fptr" as a pure virtual member, and inherit all your classes from that class.