How to get correct type hints in c++ templates - templates

template<typename T = Command::LvCommandData, typename... Args>
static T* Create(Args&&... args)
{
return new T(args);
}
The above function, of course, gets parameter hints as Args. It's perfectly normal.
However, it is too inconvenient to use, and if the parameters do not match, the error becomes complicated due to link errors.
I don't know if there is a way, but is there any hacking way to output this part like the following screenshot?

Related

Create and Call an Empty Function

Given a function signature (e.g. from a template argument), I want to create a (non-inlined) function with that signature, then call it.
The following should clarify this intent. As-written, it is not valid, since the marked line actually generates a null function pointer, not an empty function:
template <typename Function, typename... Args>
void foo(Args... args) {
Function fn_trivial = {}; //incorrect; should be empty function, not null function
fn_trivial(args...);
}
How can I create a function object here?
(Sidenote: this might seem like a weird thing to do. The reason is it's a general-purpose profiler that calls a (marked non-inline-able) test function n times to compute an average latency. A (better) semblance of the test code's cost can be obtained by subtracting the latency of a function call with the same arguments, that does nothing, in the average.)
You cannot create a local function in C++. You could create a local object type and define/call its operator(), or use a lambda—but at that point you might as well put it outside as a real function:
template <typename TypeRet, typename... Args>
TypeRet empty_function(Args... args) {
return TypeRet();
}
template <typename Function, typename... Args>
void foo(Args... args) {
empty_function<decltype( std::declval<Function>()(args...) )>(args...);
}
(Consider also adding std::forward, as-desired.)
Note that any worthwhile compiler will remove the call, even if it is marked as not-inline-able. This is because even though the function is not inlined, it does nothing, and so can be elided entirely. You can work around this in several ways, but using a volatile variable is portable to Clang, GCC, ICC, and MSVC:
#ifdef _MSC_VER
#define NOINLINE __declspec(noinline)
#else
#define NOINLINE __attribute__((noinline))
#endif
template <typename TypeRet, typename... Args>
NOINLINE TypeRet empty_function(Args... args) {
TypeRet volatile a = TypeRet();
return a;
}
See it live.

c++ template member function that changes parameters depending on template parameter

---Edit for more context---
Lets say I have a class called TempClass. As the name suggests its a template class. It has a bunch of stuff that doesnt really matter to this question, but the interesting stuff is a member function called addTo and a member variable that is a unordered_map object. Lets call it inserted. Everything in inserted was put in there using addTo. What addTo should do is make some object that is then inserted into the collection at the given key. The inserted instance should be created inside of the function rather than passed to it.
addTo(KeyType key, ...) // im looking for what I should put at ...
Basically I am stuck at everything after key. I need a way I can specify the data for the newly created instance without having to worry about the objects lifetime or complicate things with calls to std::make_xxx(shared, unique etc).
Here is how I want it to be called
TempClass<std::string> stringClass();
stringClass.addTo(whereToAddIt, "This was selected because of std::string");
TempClass<Vector3f> vectorClass();
vectorClass.addTo(someOtherLocation, 12.0f,12.0f,3.0f); //adds a vec(12.0f,12.0f,3.0f)
I have seen this done this way and if this is good practice in general id love to implement it this way.
What I have tried:
Passing a pointer to the function
------> Works but is stupid. It required me to pay attention to deleting the object
Passing a temporary object and copying it before inserting
------> Works but I dislike having to copy the object just to delete it. It seems redunant and is not optimal for my specific application.
I have seen this done before, but I cant remember where (trust me I have tried to remember this, since if I could I could just look it up myself). Please explain to me in detail how to do this and how it works.
Please help me figure this out!
You can use overloads, and then enable a certain overload when your templated type is a certain type
#include <type_traits> //for enable_if and is_same
template<typename T>
class MyClass
{
public:
template<typename = std::enable_if<std::is_same_v<T, std::string>>>
void someMember(string param1, int param2);
template<typename = std::enable_if<std::is_same_v<T, Vector3f>>>
void someMember(string param1, int param2, int param3);
};
This will select the first overload is T is std:string, and the second overload if T is a Vector3f.
Edit: Looking at your edited question, a much better approach would be to just pass an instance of T to your addTo function. Like:
void addTo(std::string key, T const& value);
EDIT2: I think I finally know what you actually want. You need to use variadic templates and perfect forwarding. This might seem confusing, so I will give you code:
template<typename KeyType, typename... Args>
void addTo(KeyType key, Args&&... args)
{
//now construct the new element with:
T elem(std::forward<Args>(args)...);
}
You will need to include the utility header. For more information on variadic templates see cppreference
You can use variadic template and perfect forwarding to emplace a k/v pair:
template<class K, class V>
struct foo {
template<class... Args>
void addTo(K k, Args&&... args) {
mp.emplace(
std::piecewise_construct,
std::forward_as_tuple(k),
std::forward_as_tuple(std::forward<Args>(args)...)
);
}
std::unordered_map<K, V> mp;
};

Multiple parameter packs of different types

Okay so what I have is as follows:
template< int... ints, class... classes >
magic_return_type<ints..., classes...> func() { \* snip *\ }
template< int... ints, class... classes >
class obj
{
public:
obj() : x(func<ints, classes>()) {}
private:
magic_return_type<ints..., classes...> x;
};
Apparently clang++ and g++ let func get away with having multiple parameter packs, but obj cannot, because I receive the following error:
error: parameter pack 'ints' must be at the end of the template parameter list
For this problem you can assume that magic_return_type exists, and is "logically correct". (it ends up being a boost::fusion::vector of some stuff in the non-toy version).
The possible solutions/workarounds that I see:
Find some magical way I don't know about to have it do what I want.
Pass boost::mpl objects to obj instead of parameter packs, which solves obj's problem, but I don't know how to convert them to parameter-packs for func.
Pass boost::mpl objects to both obj and func which I don't really mind doing, but I feel like it's changing upstream to fix a downstream problem, so I thought I'd check on SO to see if people could come up with something smarter.
Any ideas guys? Is option #3 the only way to go?
Cheers!

std::enable_if as single argument of constructor

I'm fairly new to template metaprogramming and have been working through some of the concepts - however, I've been stumped a little by this particular snippet I came across.
template<class TAG, typename... DATATYPES>
struct Message {
Message (typename std::enable_if<sizeof...(DATATYPES) >= 1>) {
}
... (various other constructor declarations here)
std::tuple<DATATYPES...> m_data;
};
I had assumed when reading it that it was enabling the default constructor if there were one or more DATATYPES arguments, but having tested it all I got was a compilation error.
I would appreciate any assistance in helping my understanding of this snippet as I understand what enable_if is supposed to be doing but within this context I don't seem to be able to wrap my head around what's actually happening.
EDIT: I guess this is less a question of 'how do I achieve this particular effect?' and more along the lines of 'what is this code actually producing, and does it match up with what I understood to be the intention of the original author?'
std::enable_if is not used correctly if not followed by ::type. std::enable_if<expr> itself is a fairly useless struct type.
A correct way of conditionally enabling the default constructor:
template<class TAG, typename... DATATYPES>
struct Message {
private:
struct dummy_type {};
public:
template <typename T = std::tuple<DATATYPES...>>
Message(
typename std::enable_if<std::tuple_size<T>() >= 1, dummy_type>::type
= dummy_type{}
) {}
//...
};
Live at coliru.
Member function signatures are a part of class definition and need to be resolved when the class is instantiated. This means that compiler tries enable_if, too, and if the conditon is not fullfilled, it discovers that it doesn't have the nested type - hard error.
To make SFINAE work, you need to make the constructor a template and have enable_if depend on a template parameter. See #acheplers's answer for example.
What the code in OP does is a weird way of asserting the size of DATATYPE pack, which would be done with static_assert much more clearly. Or, maybe the author just didn't know how to do SFINAE correctly.

Boost's Interpreter.hpp example with class member functions

Boost comes with an example file in
boost_1_41_0\libs\function_types\example
called interpreter.hpp and interpreter_example.hpp
I am trying to create a situation where I have a bunch of functions of different arguments, return types, etc all register and be recorded to a single location. Then have the ability to pull out a function and execute it with some params.
After reading a few questions here, and from a few other sources I think the design implemented in this example file is as good as I will be able to get. It takes a function of any type and allows you to call it using a string argument list, which is parsed into the right data types.
Basically its a console command interpreter, and thats probably what its meant to illustrate.
I have been studying the code and poking around trying to get the same implementation to accept class member functions, but have been unsuccessful so far.
I was wondering if someone could suggest the modifications needed, or maybe worked on something similar and have some same code.
In the example you'll see
interpreter.register_function("echo", & echo);
interpreter.register_function("add", & add);
interpreter.register_function("repeat", & repeat);
I want to do something like
test x;
interpreter.register_function("classFunc", boost::bind( &test::classFunc, &x ) );
But this breaks the any number of arguments feature.
So I am thinking some kind of auto generating boost::bind( &test::classFunc, &x, _1, _2, _3 ... ) would be the ticket, I just am unsure of the best way to implement it.
Thanks
I've been working on this issue and i've somewhat succeeded to make the boost interpreter accept the member function such as:
// Registers a function with the interpreter,
// will not compile if it's a member function.
template<typename Function>
typename boost::enable_if< ft::is_nonmember_callable_builtin<Function> >::type
register_function(std::string const& name, Function f);
// Registers a member function with the interpreter.
// Will not compile if it's a non-member function.
template<typename Function, typename TheClass>
typename boost::enable_if< ft::is_member_function_pointer<Function> >::type
register_function(std::string const& name, Function f, TheClass* theclass);
The enable_if statement is used to prevent the use of the wrong method at the compile time. Now, what you need to understand :
It uses the boost::mpl to parse trough the argument's parameter types of the callable builtin (which is basically a function pointer)
Then, prepares a fusion vector at the compile-time (which is a vector that can stock different objects of different types at the same time)
When the mpl is done parsing every arguments, the "parsing" apply method will fork in the "invoke" apply method, following the templates.
The main issue is that the first argument of a member callable builtin is the object which holds the called method.
As far a I know, the mpl cannot parse the arguments of something else than a callable builtin (i.e A Boost::Bind result)
So, what needs to be done is simply add one step to the "parsing" apply, which would be to add the concerned object to the apply loop! Here it goes:
template<typename Function, typename ClassT>
typename boost::enable_if< ft::is_member_function_pointer<Function> >::type
interpreter::register_function( std::string const& name,
Function f,
ClassT* theclass);
{
typedef invoker<Function> invoker;
// instantiate and store the invoker by name
map_invokers[name]
= boost::bind(&invoker::template apply_object<fusion::nil,ClassT>
,f,theclass,_1,fusion::nil());
}
in interpreter::invoker
template<typename Args, typename TheClass>
static inline
void
apply_object( Function func,
TheClass* theclass,
parameters_parser & parser,
Args const & args)
{
typedef typename mpl::next<From>::type next_iter_type;
typedef interpreter::invoker<Function, next_iter_type, To> invoker;
invoker::apply( func, parser, fusion::push_back(args, theclass) );
}
This way, it will simply skip the first argument type and parse everything correctly.
The method can be called this way: invoker.register_function("SomeMethod",&TheClass::TheMethod,&my_object);
I am not into fusion and therefore don't see how to fix it in a simple and elegant way (i mainly don't see how member functions are supposed to work), but i worked on something similar that might be an alternative for you.
If you want to take a look at the result, it is in the Firebreath repository.
In short:
MethodConverter.h contains the main functionality
the ugly dispatch_gen.py generates that header
ConverterUtils.h contains the utility functionality like conversion to the target types
TestJSAPIAuto.h and jsapiauto_test.h contain a unit test that shows it in action
The main changes would probably involve to strip the FB-specific types, tokenize the input sequence before invoking the functors and supply your own conversion functions.
One option is to make a set of templates
template <class T, class Ret>
void register_function(const char *name, Ret (T::*fn)()) { /* boost::bind or your way to register here */ }
template <class T, class Ret, class Arg1>
void register_function(const char *name, Ret (T::*fn)(Arg1)) { /*...*/ )
And so on.. Until C++0x come with its variadic templates, you can use Boost.Preprocessor to generate required amount of templates