An interface template looks like this:
interface TemplateInterface(T) {
T x();
}
This interface needs to be used as a parameter for a function, but I'd like to avoid defining the template type in the function signature. Is there some way to just have the function signature accept whatever template type is being passed to the function, like a templated function?
For example:
// no good, do not want to constrain template type at this point
void func1(TemplateInterface!int parm1) {...
// this would be better, but the syntax is wrong apparently
void func1(TemplateInterface parm1) {...
I believe what you want is
void func1 (T) (TemplateInterface!T parm1) {...
Here, func1 has a compile-time parameter T, which is used in the argument's type TemplateInterface!T, and a run-time parameter parm1 of the aforementioned type.
A more complete example:
import std.stdio;
interface TemplateInterface(T) {
T x();
}
class Instance(T) : TemplateInterface !(T) {
T x() {return cast (T) (1.2345);}
}
void func1 (T) (TemplateInterface!T parm1) {
writeln (typeof(parm1.x()).stringof, " ", parm1.x());
}
void main() {
auto a = new Instance !(int) ();
auto b = new Instance !(real) ();
func1(a); // int 1
func1(b); // real 1.2345
}
You can use a template function with a template constraint to achieve this:
import std.traits: isInstanceOf;
interface TemplateInterface(T) {
T x();
}
void func1(TemplateInterfaceInstance)(TemplateInterfaceInstance parm1)
if(isInstanceOf!(TemplateInterface, TemplateInterfaceInstance))
{ ...
The template constraint is not strictly needed, but you get better error messages with it when trying to pass something to func1 which is not an instance of TemplateInterface.
Related
I have a fairly big project that, regarding this question,
I can summarize with
this structure:
void do_something()
{
//...
}
template<typename F> void use_funct(F funct)
{
// ...
funct();
}
int main()
{
// ...
use_funct(do_something);
}
All is working ok until someone (me) decides to reformat a little
minimizing some functions, rewriting
as this minimum reproducible example:
void do_something(const int a, const int b)
{
//...
}
void do_something()
{
//...
do_something(1,2);
}
template<typename F> void use_funct(F funct)
{
// ...
funct();
}
int main()
{
// ...
use_funct(do_something);
}
And now the code doesn't compile with
error: no matching function for call
where use_funct is instantiated.
Since the error message was not so clear to me
and the changes were a lot I wasted a considerable
amount of time to understand that the compiler
couldn't deduce the template parameter
because do_something could now refer to
any of the overloaded functions.
I removed the ambiguity changing the function name,
but I wonder if there's the possibility to avoid
this error in the future not relying on template
argument deduction.
How could I specify in this case the template argument for do_something(), possibly without referring to a function pointer?
I haven't the slightest idea to express explicitly:
use_funct<-the-one-with-no-arguments->(do_something);
You can wrap the function in a lambda, or pass a function pointer after casting it to the type of the overload you want to call or explicitly specify the template parameter:
use_funct([](){ do_something (); });
use_funct(static_cast<void(*)()>(do_something));
use_funct<void()>(do_something);
Wrapping it in a lambda has the advantage, that it is possible to defer overload resolution to use_func. For example:
void do_something(int) {}
void do_something(double) {}
template<typename F> void use_funct(F funct) {
funct(1); // calls do_something(int)
funct(1.0); // calls do_something(double)
}
int main() {
use_funct([](auto x){ do_something (x); });
}
[...] possibly without referring to a function pointer?
I am not sure what you mean or why you want to avoid that. void() is the type of the function, not a function pointer. If you care about spelling out the type, you can use an alias:
using func_type = void();
use_funct<func_type>(do_something);
I have class with some calls inside. Every call taking like an argument two callbacks: for successful and error case respectivelly. Inside of these callbacks I have to call for both cases overloaded function with name like "answerCallName", but pass different params to it depending on success.
So with rising a number of such calls it becomes annoying to define for every call two callback inside.
So I'm searching the solution better than "copy paste".
I'm looking on templates. But cannot find any way to use one function name like argument to use it for different overloads inside template.
I've tried to make some templates, but obviously failed, so far as template requeres exect function pointer and in case function is overloaded I need to explicitly show this type.
//========================================================
//Here is exaple of class (library) with a lot of calls
class SomeLargeClass
{
protected:
void callToDoSmth1(std::function<void(int)>, std::function<void(std::string)>);
void callToDoSmth2(std::function<void(char)>, std::function<void(std::string)>);
void callToDoSmth3(std::function<void(const A & a)>, std::function<void(std::string)>);
...
};
//========================================================
//Here is calls I should call when one of callbacks are called. Also this part is placed in the library
class ResponsesClass
{
protected:
void answerCallToDoSmth1(int);
void answerCallToDoSmth1(std::string);
void answerCallToDoSmth2(char);
void answerCallToDoSmth2(std::string);
void answerCallToDoSmth3(const A & a);
void answerCallToDoSmth3(std::string);
...
}
//========================================================
//Here is my class
class MyProxy: public SomeLargeClass, public ResponsesClass
{
...
void action1();
}
//========================================================
//
void MyProxy::action1()
{
auto success = [](int value)
{
ResponsesClass::answerCallToDoSmth1(value);
}
auto error = [](std::string value)
{
ResponsesClass::answerCallToDoSmth1(value);
}
SomeLargeClass::callToDoSmth1(success, error);
}
So I'm looking for something like:
template<class ResponseFn, class ReturnType, class Object>
std::pair<
std::function<void(ReturnType)>,
std::function<void(std::string)>
>
MyProxy::createCallbacks(ResponseFn responseFn, Object object)
//--------------------------------------------------------------------
{
auto onSuccess = [this, responseFn] (ReturnType value)
{
(object->*responseFn)(value);
};
auto onError = [object, responseFn](std::string value)
{
(object->*responseFn)(value);
};
return std::pair<decltype(onSuccess), decltype(onError)>(onSuccess, onError);
}
to create callbacks for every call with one function call.
void MyProxy::actionX()
{
auto callbacks = createCallbacks<int>(&MyProxy::answerCallToDoSmthX); //not working due to diffrent function addresses
SomeLargeClass::callToDoSmthX(callbacks.first, callbacks.second);
}
I'm just intresting could it be solved without makroses and generators.
Is it planned to be resolved in future standarts?
Since C++14 lambdas can have auto parameters:
void MyProxy::action1()
{
auto success_and_error = [=](auto... value)
{
ResponsesClass::answerCallToDoSmth1(value...);
};
SomeLargeClass::callToDoSmth1(success_and_error, success_and_error);
}
This effectively makes the lambda's operator() a variadic template function that takes an arbitrary number of parameters. That way the lambda can implicitly be converted to std::function<void(int)>, std::function<void(std::string)>, std::function<void(std::string, int, float, int, A, B, C)>, and whatever else you like, as long as there is a corresponding overload of SomeLargeClass::callToDoSmth1() that takes the same parameters.
Suppose I want to have different handlers for different kind of messages, each message is identified by an int. I want to define each handler as an instantiation of a template method.
The idea is something like this:
handlers.h
enum Handler {
MESSAGE1,
MESSAGE2
};
template<MESSAGE1>
void handle() {
}
main.cpp
int main()
{
handle<Handler::MESSAGE>();
}
Of course this code does not compile because MESSAGE1 is not a type.
So, how could I create a different type for each message ? Also, I'd like to maintain the use of these types as meaningful as possible (hence the use of enums).
You want what's called non-type template parameters with template specialization:
template<Handlers H> void handle(); // default
template<> void handle<MESSAGE1>() {
// ...
}
template<> void handle<MESSAGE2>() {
// ...
}
You can use std::integral_constant (or write your own empty type wrapper to do the same thing) to wrap your enums into types:
template <Handler H>
using handle_t = std::integral_constant<Handler, H>;
And then overload on different types:
void handle(handle_t<MESSAGE1> ) { ... }
void handle(handle_t<MESSAGE2> ) { ... }
which you can call via:
handle(handle_t<MESSAGE1>{} );
Let's assume we have the following class A:
class A
{
public:
void sum(int x);
};
And we have a function f, which gets a C-style callback with one parameter of type int and calls it:
typedef void (*Callback)(int);
void f(Callback cb)
{
cb(5);
}
Is there any way in C++ to curry a method A::print on an object of type A and pass it to the function f? Something like this:
void main()
{
A a;
auto curry_a = ??; // something like curry_a = [&](int x) { a.sum(x) };
f(curry_a);
}
std::bind and lambda-function are not a solution, because they create objects of type std::function<> with overloaded operator(). It looks like currying in C++, but it cannot be used in my case. I need a real function pointer, i.e. generate code in real time.
You are out of luck, it can't be done in a satisfactory way: The only thing that is exactly a C-compatible function pointer is a function (or class-function but not instance function).
So, you'd have to create a function that fixes a parameter, like the this of a member function. The only way to set this parameter is through a global variable:
A *instance;
void (A::*a_fun)(int);
void applicator(int arg) { instance->*a_fun(arg); }
//...
int main() {
A a;
instance = &a;
a_fun = &A::sum;
f(applicator);
// ...
That is the only way to provide context to a plain function, through global variables.
Has anyone ever used pointers/references/pointer-to-member (non-type) template parameters?
I'm not aware of any (sane/real-world) scenario in which that C++ feature should be used as a best-practice.
Demonstation of the feature (for pointers):
template <int* Pointer> struct SomeStruct {};
int someGlobal = 5;
SomeStruct<&someGlobal> someStruct; // legal c++ code, what's the use?
Any enlightenment will be much appreciated!
Pointer-to-function:
Pointer-to-member-function and pointer-to-function non-type parameters are really useful for some delegates. It allows you to make really fast delegates.
Ex:
#include <iostream>
struct CallIntDelegate
{
virtual void operator()(int i) const = 0;
};
template<typename O, void (O::*func)(int)>
struct IntCaller : public CallIntDelegate
{
IntCaller(O* obj) : object(obj) {}
void operator()(int i) const
{
// This line can easily optimized by the compiler
// in object->func(i) (= normal function call, not pointer-to-member call)
// Pointer-to-member calls are slower than regular function calls
(object->*func)(i);
}
private:
O* object;
};
void set(const CallIntDelegate& setValue)
{
setValue(42);
}
class test
{
public:
void printAnswer(int i)
{
std::cout << "The answer is " << 2 * i << "\n";
}
};
int main()
{
test obj;
set(IntCaller<test,&test::printAnswer>(&obj));
}
Live example here.
Pointer-to-data:
You can use such non-type parameters to extend the visibility of a variable.
For example, if you were coding a reflexion library (which might very useful for scripting), using a macro to let the user declare his classes for the library, you might want to store all data in a complex structure (which may change over time), and want some handle to use it.
Example:
#include <iostream>
#include <memory>
struct complex_struct
{
void (*doSmth)();
};
struct complex_struct_handle
{
// functions
virtual void doSmth() = 0;
};
template<complex_struct* S>
struct csh_imp : public complex_struct_handle
{
// implement function using S
void doSmth()
{
// Optimization: simple pointer-to-member call,
// instead of:
// retrieve pointer-to-member, then call it.
// And I think it can even be more optimized by the compiler.
S->doSmth();
}
};
class test
{
public:
/* This function is generated by some macros
The static variable is not made at class scope
because the initialization of static class variables
have to be done at namespace scope.
IE:
class blah
{
SOME_MACRO(params)
};
instead of:
class blah
{
SOME_MACRO1(params)
};
SOME_MACRO2(blah,other_params);
The pointer-to-data template parameter allows the variable
to be used outside of the function.
*/
std::auto_ptr<complex_struct_handle> getHandle() const
{
static complex_struct myStruct = { &test::print };
return std::auto_ptr<complex_struct_handle>(new csh_imp<&myStruct>());
}
static void print()
{
std::cout << "print 42!\n";
}
};
int main()
{
test obj;
obj.getHandle()->doSmth();
}
Sorry for the auto_ptr, shared_ptr is available neither on Codepad nor Ideone.
Live example.
The case for a pointer to member is substantially different from pointers to data or references.
Pointer to members as template parameters can be useful if you want to specify a member function to call (or a data member to access) but you don't want to put the objects in a specific hierarchy (otherwise a virtual method is normally enough).
For example:
#include <stdio.h>
struct Button
{
virtual ~Button() {}
virtual void click() = 0;
};
template<class Receiver, void (Receiver::*action)()>
struct GuiButton : Button
{
Receiver *receiver;
GuiButton(Receiver *receiver) : receiver(receiver) { }
void click() { (receiver->*action)(); }
};
// Note that Foo knows nothing about the gui library
struct Foo
{
void Action1() { puts("Action 1\n"); }
};
int main()
{
Foo foo;
Button *btn = new GuiButton<Foo, &Foo::Action1>(&foo);
btn->click();
return 0;
}
Pointers or references to global objects can be useful if you don't want to pay an extra runtime price for the access because the template instantiation will access the specified object using a constant (load-time resolved) address and not an indirect access like it would happen using a regular pointer or reference.
The price to pay is however a new template instantiation for each object and indeed it's hard to think to a real world case in which this could be useful.
The Performance TR has a few example where non-type templates are used to abstract how the hardware is accessed (the hardware stuff starts at page 90; uses of pointers as template arguments are, e.g., on page 113). For example, memory mapped I/O registered would use a fixed pointer to the hardware area. Although I haven't ever used it myself (I only showed Jan Kristofferson how to do it) I'm pretty sure that it is used for development of some embedded devices.
It is common to use pointer template arguments to leverage SFINAE. This is especially useful if you have two similar overloads which you couldn't use std::enable_if default arguments for, as they would cause a redefinition error.
This code would cause a redefinition error:
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void foo (T x)
{
cout << "integral";
}
template <typename T, typename = std::enable_if_t<std::is_floating_point<T>::value>>
void foo (T x)
{
cout << "floating";
}
But this code, which utilises the fact that valid std::enable_if_t constructs collapse to void by default, is fine:
// This will become void* = nullptr
template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
void foo (T x)
{
cout << "integral";
}
template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
void foo (T x)
{
cout << "floating";
}
Occasionally you need to supply a callback function having a particular signature as a function pointer (e.g. void (*)(int)), but the function you want to supply takes different (though compatible) parameters (e.g. double my_callback(double x)), so you can't pass its address directly. In addition, you might want to do some work before and after calling the function.
It's easy enough to write a class template that tucks away the function pointer and then calls it from inside its operator()() or some other member function, but this doesn't provide a way to extract a regular function pointer, since the entity being called still requires the this pointer to find the callback function.
You can solve this problem in an elegant and typesafe way by building an adaptor that, given an input function, produces a customised static member function (which, like a regular function and unlike a non-static member function, can have its address taken and used for a function pointer). A function-pointer template parameter is needed to embed knowledge of the callback function into the static member function. The technique is demonstrated here.