I am trying use a variadic template in an && statement, but i dont know how to actually do it. Can somebody explain to me how i can programm a function like this one:
using EntitySet = std::vector<Entity>;
template<typename... TArgs>
EntitySet getEntitesWith()
{
EntitySet entitySet;
for(const Entity& entity : m_entitySet)
{
if (entity.hasComponent<T1>() && entity.hasComponent<T2>() && ...)
{
entitySet.push_back(entity);
}
}
return entitySet;
}
entity.hasComponent<>() returns true if the entity has a Component of the type that is passed into the function
Edit:
i just tried the Fold Expression in c++17 and when i tried to do it like #Igor Tandetnik and #oisyn told me to i got an Unexpected ... Token Error.
But when i wrote the code like this:
if (( ... && entity.hasComponent<TArgs>()))
With an extra () i got an internal compiler error and have no idea on what im doing wrong.
anybody have an idea on why this is happening?
Related
I'm trying to write a function that checks if the variable being cast can fit in the destination type, and assert() if not. Right now this is what I came up with. I didn't test it yet. I would like to make the template figure out the type of the varible being passed automatically, with something like typeid, although I don't really know what typeid really is. Is that possible? Also, I don't know much about templates.
template<typename from_T, typename to_T>
static inline to_T safe_cast(from_T variable)
{
assert(variable >= std::numeric_limits<to_T>::min());
assert(variable <= std::numeric_limits<to_T>::max());
return static_cast<to_T>(variable);
}
Well, if that is actually some function that already does this that I don't know of I will be glad to hear.
C++ Core Guidelines already has a gsl::narrow
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
You can see the Microsoft implementation here
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
template <class T, class U>
constexpr T narrow(U u) noexcept(false)
{
constexpr const bool is_different_signedness =
(std::is_signed<T>::value != std::is_signed<U>::value);
const T t = narrow_cast<T>(u);
if (static_cast<U>(t) != u || (is_different_signedness && ((t < T{}) != (u < U{}))))
{
throw narrowing_error{};
}
return t;
}
You can see the explanation of the implementation on this SO post (it's for an older version of the implementation, but nothing substantially changed, so the answer still applies).
This is on os x yosemite with clang from xcode 7.2 in clion.
I'm iterating through a query from a postgresql db and adding the result to a json object.
for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) {
participants["participants"] += { \
{"id", c[0].as<std::string>()},
{"location", c[1].as<std::string>()},
{"racename", c[2].as<std::string>()},
{"racestart_at", c[3].as<std::string>()},
{"ended_at", static_cast<bool>(c[9].size()) ? c[9].as<std::string>() : ""},
{"racetime", static_cast<bool>(c[10].size()) ? c[10].as<std::string>() : ""}
};
}
Some of the columns have null values so I test for that casting to bool in a ternary operator and either return the result or an empty string. To make it a bit cleaner I tried to add a template function with the example from http://www.cprogramming.com/tutorial/templated_functions.html and had this:
template <class T>
std::string column_content(T a) {
return static_cast<bool>(a.size()) ? a.as<std::string>() : "";
}
When I try to compile the program I get the error:
Database.cpp:9:44: error: use 'template' keyword to treat 'as' as a dependent template name
return static_cast<bool>(a.size()) ? a.as<std::string>() : "";
^
template
I looked at Cast Chars To Int in Template Function and http://www.cplusplus.com/doc/oldtutorial/templates/ and other suggestions from google but it looks like I'm using the wrong syntax but I can't spot it.
If I could use a template function adding to json could then look like
{"start_at", column_content(c[8])}
regards
Claus
I changed it to a function for the time being. The type passed is pqxx::result::field as per http://pqxx.org/devprojects/libpqxx/doc/2.6.9/html/Reference/a00259.html#2a9d36599b217ebfde2cac4633856ac0.
std::string column_content(pqxx::result::field a) {
if (static_cast<bool>(a.size())) {
return a.as<std::string>();
} else {
return "";
}
}
I have a recursive variadic templated method that is called from a non-recursive variadic templated method (probably not relevant but I'll mention it just in case):
template < class T, class UnaryPredicate, typename... UnaryPredicates >
static bool checkPredicate( const T obj,
const UnaryPredicate& p,
UnaryPredicates... predicates )
{
bool output = p( obj );
if ( output && sizeof...( UnaryPredicates ) ) {
output = checkPredicate( obj, predicates... ); // The problem line.
}
return output;
}
However when called with:
.. = checkPredicate< Sy_simObject*, VisiblePredicate< Sy_simObject* >( .. );
It gives me the following error:
error: no matching function for call to
'Sy_project::checkPredicate(Sy_simObject* const&)'
I understand that the error is telling me that UnaryPredicates is empty, and there is no overload for just T, and sure enough if I put one in it compiles fine. But I don't understand how it could have gotten that far with the sizeof...( UnaryPredicates ) check in the conditional? Surely if there were no more it would have evaluated as false and the recursion would have ended?
I can fix it by just adding the overload, by I really want to understand why it doesn't work now.
Because if(cond) { body } is a runtime if. The fact that the compiler can know before-hand at compile time that it doesn't need to branch at runtime can be used to optimize the generated code, but it must not influence whether it complains about certain parts of the code.
If the code of the body is invalid if cond is false, the compiler will complain. What you are looking for is a static if, which controls whether certain parts of your code is processed by the compiler or not. There are proposals for such a thing for the next C++ version, but current C++ does not have such a construct.
I'm wrapping the Windows API, and I wish to make error checking easy to use, and helpful. Currently, I have a global error object, with a function set to handle a new error. The set function takes four arguments: bool Error::set (const int code, const char * file, const char * const function, const int line); The function uses the file, function, and line arguments to display them in a nicely formatted message.
To ease the setting of errors, there is a macro #define setError() error.set (GetLastError(), __FILE__, __FUNCTION__, __LINE__); This way I'm able to use setError() at any time to respond to an error that an API function has set by adding it after I call that API function.
Unfortunately, this causes the code to look something like this:
SomeAPIFunction();
setError();
AnotherAPIFunction();
setError();
There is also a problem with constructors:
MyClass:MyClass()
: a (SomeAPIFunction), b (AnotherAPIFunction)
{
setError(); //what if both functions set an error?
}
As you can see, by using member initializer syntax, I'm actually limiting myself.
One way to fix this would be to wrap every API function:
int someAPIFunction()
{
int ret = SomeAPIFunction();
setError();
return ret;
}
The function portion of the error message would tell me which function originated the error. Of course, that has to be the worst possible way of dealing with this.
The solution, it seems, is to use variadic templates. The problem is, I have no idea what I'm supposed to be doing to get them working for this. I'd imagine the final code looks something like one of the following:
wrap<int, SomeAPIFunction (5)>();
wrap<int, SomeAPIFunction, 5>();
wrap<int, SomeAPIFunction> (5);
I've read things on beginning variadic templates, but they've all left me clueless of how to set up something like this. Could anyone point me in the right direction?
I found the following on a similar question:
#include <iostream>
template<void f(void)>
struct Wrap {
void operator()() const {
std::cout << "Pre call hook" << std::endl;
f();
}
};
namespace {
void test_func() {
std::cout << "Real function" << std::endl;
}
}
const Wrap<&test_func> wrapped_test_func = {};
int main() {
wrapped_test_func();
return 0;
}
The respondent noted that variadic templates would be a necessity to make this generic enough. It's a start, but I'm lost and grateful of any help on the matter.
I think you'll be able to make it work with this syntax:
wrap(&SomeAPIFunction, arg1, arg2);
The key is to let the compiler use type deduction to determine the template type parameters, since they get pretty messy in a hurry.
The code should look something like:
template<typename TRet, typename... TArgs>
TRet wrap( TRet(WINAPI *api)(TArgs...), TArgs... args )
{
return api(args...);
}
Naturally, you'll want to use a macro to hide the address-of-function operator, use stringizing to store the function name, and store the filename and line number also, passing all of that to the actual variadic function. You'll need variadic macros for that. In fact, could you do all of this just with variadic macros and no templates?
I have one template function which will take a pointer type and i have instantiated it before calling.
i have written function with its dummy implementation as follows:
template<T>fun_name( const T *p )
{
//written functionality which will give me class name that i will store into string Variable
e.g. i got output like this string Var = "First_class" or string Var = "Second_class"
//Using this class name i will call one function of that class
if(Var == "Fisrt_class")
{
First_class::static_function_name(p);
}
if(Var == "Second_class")
{
Second_class::static_function_name(p);
}
}
and in global scope i instantiated this function for two variables as like below:
template<first_class>static_function_name(const First_class *)
template<Second_class>static_function_name(const Second_class *)
above code gives me error that
error: no matching function call in Second_class::static_function_class(const Fisrt_class*)
error: no matching function call in First_class::static_function_class(const Second_class*)
thanks in advance!
I think this :
template<typename T> // template<class T> is equally valid!
void fun_name( const T *p )
{
T::static_function_name(p);
}
is enough!
Two more errors is fixed in the above code:
Mention the keyword typename in template<T> in your code. You can also write template<class T> which is equally valid.
Mention the return type of the function template as well.
Your function template "calls" each of the static functions in each class. Even though program flow may never get to one of the calls, the compiler still has to figure out the code for each of them.
So when you instantiate:
template<first_class>fun_name(const first_class*)
the compiler tries to compile the entire function with T = first_class, which means at some point inside the function, it will try to compile the function call:
Second_class::static_function_name(p);
But since variable p is a pointer to first_class, the compiler doesn't find the function.
If you want conditional compilation, try specializing your function instead so the compiler only compiles the function call you intended for each type:
template <T> fun_name (const T* p);
template <> fun_name<first_class>(const first_class* p) {
first_class::static_function_name(p);
}
template <> fun_name<second_class>(const second_class* p) {
second_class::static_function_name(p);
}
Alternatively, you can use member functions which seem to be intended for what you are trying to do here. Then you can create objects and call the functions directly:
first_class f;
second_class s;
f.function();
s.function();
try changing to ,
template<typename T>
void fun_name( const T *p )
{
T::static_function_name(p);
}