I have the following function defined:
template<class KEY, class VALUE, class HASH_FUNCTION,
class COMPARATOR_FUNCTION, class GREATER_THAN_FUNCTION>
bool Test3(size_t szCount, double dLoadFactor, vector<KEY>& vVals,
const HASH_FUNCTION& hf, const COMPARATOR_FUNCTION& cf,
const GREATER_THAN_FUNCTION& gf)
Then I call it in main().
int main()
{
vector<char*> vVals = GetWords("enwik8", 128*1024*1024);
SHash sh;
SHComp cf;
SHGreater gf;
Test3(1000, 0.7f, vVals, sh, cf, gf);
return 0;
}
And I get this error thrown at me:
/home/duminda/main.cpp:313: error: no matching function for call to
‘Test3(int, float, std::vector<char*, std::allocator<char*> >&, SHash&,
SHComp&, SHGreater&)’
I maybe missing something obvious. Any help would be appreciated. Thanks.
Looking at the function declaration, it has a template parameter V which isn't used anywhere in the actual parameter list. So it can't be deduced automatically at the call site.
Try just defining it as this instead:
template<class K class HF, class CF, class GF>
bool Test3(size_t szCount, double dLoadFactor, vector<K>& vVals, const HF& hf, const CF& cf, const GF& gf)
By the way, you might want to consider spending 5 seconds coming up with meaningful names. If V had had a sensible name, it might have been more obvious that it serves no purpose.
There is a template parameter VALUE that has not been resolved. It is never used.
Your function should already be able to derive this type if it is using it somewhere in the body. If it derives from a different template parameter, ensure you have a way of doing so. Possibly that template parameter has an internal typedef, for example if one of your comparison functions compares values of this type, they could have a value_type typedef.
Be certain to use typename in the body to get to this type if it is done that way.
Given the edited declaration
template<class KEY, class VALUE, class HASH_FUNCTION,
class COMPARATOR_FUNCTION, class GREATER_THAN_FUNCTION>
bool Test3(size_t szCount, double dLoadFactor, vector<KEY>& vVals,
const HASH_FUNCTION& hf, const COMPARATOR_FUNCTION& cf,
const GREATER_THAN_FUNCTION& gf);
and the comment: V is used by the function Test3. Is there a way for me to tell the compiler what the type of V is?
The problem with Test3(1000, 0.7f, vVals, sh, cf, gf); is that the compiler cannot deduce the template argument VALUE. But you can explicitly list template arguments to a function name like this:
Test3<const char*, value_type>(1000, 0.7f, vVals, sh, cf, gf);
Here the first two template arguments KEY=const char* and VALUE=value_type are given in < angle brackets >, and the rest can be deduced by the compiler.
If you change the order of KEY and VALUE in the template declaration, you could skip providing the KEY and let that be deduced:
template<class VALUE, class KEY, class HASH_FUNCTION,
class COMPARATOR_FUNCTION, class GREATER_THAN_FUNCTION>
bool Test3(size_t szCount, double dLoadFactor, vector<KEY>& vVals,
const HASH_FUNCTION& hf, const COMPARATOR_FUNCTION& cf,
const GREATER_THAN_FUNCTION& gf);
// ...
Test3<value_type>(1000, 0.7f, vVals, sh, cf, gf);
Related
I would like to implement a class wrapper for database.
Currently, I'm working on a createTable function.
The way I have tried to make it work is, that the user specifies the types
as a template parameters, and the column names as an initialiser list,
this is the template of the function:
template <typename ... Ts>
bool createTable(const std::string & tableName, const std::initializer_list<std::string> & columnNames);
And this is the body of the method:
template<typename ... Ts>
bool DatabaseConnection::createTable(const std::string &tableName, const std::initializer_list<std::string> & columnNames)
{
constexpr size_t num_cols = sizeof...(Ts);
assert(num_cols == columnNames.size());
auto typetuple = std::tuple<Ts...>();
std::vector<std::tuple<std::string, std::string>> columnNameAndType(num_cols);
auto columnNameIterator = columnNames.begin();
for(unsigned it = 0; it++ < columnNames.size(); it++){
typedef std::tuple_element<it, typetuple>::type c; // non-type template argument is not a constant expression
if(is_same<c, int> ...) //pseudocode
std::string dbtype = "INTEGER"; //pseudocode
}
}
Sadly, the tuple_element line doesn't work, because it's not really a
constant expression.
Now, someone might ask, why I want to call it like this:
createTable<int, std::string>("Users", {"ID", "Name"});
instead of just passing two initialiser lists?
Well I just want to distance the user from the interface - If I were able to determine
the it-h type I could just use something like decltype or is_same to determine the type used in database creation query - the user just says what type he/she wants and the Database class
determines the best database type to match the user's request.
Now, it could still be made with initaliser lists, but it wouldn't be compile time, and
I'm just curious to see if it's possible at comple time.
I hope my explanation of the problem is sufficient.
Of course this is mostly a theoretical problem, but I think many people
would be interested in such a syntax, and I haven't found any solutions on the internet yet.
This interface is certainly possible.
A for loop isn't going to do it, because one statement/variable/expression/etc. can't have different types on different evaluations of a for substatement. The loop will need to be via pack expansion instead.
One or more private helper member functions could help for this. It would be possible to get it all in one function definition using a generic lambda, but a little unpleasant.
// private static
template <typename T>
std::string DatabaseConnection::dbTypeName()
{
if constexpr (std::is_same_v<T, int>)
return "INTEGER";
// ...
else
static_assert(!std::is_same_v<T,T>, "Unsupported type argument");
}
template<typename ... Ts>
bool DatabaseConnection::createTable(
const std::string &tableName,
std::initializer_list<std::string> columnNames)
{
constexpr size_t num_cols = sizeof...(Ts);
assert(num_cols == columnNames.size());
std::vector<std::tuple<std::string, std::string>> columnNameAndType;
auto columnNameIterator = columnNames.begin();
(columnNameAndType.emplace_back(*columnNameIterator++, dbTypeName<Ts>()), ...);
// ...
}
I am looking to move some of the code of within a template method to a non-template method in order to decrease the binary size.
There is a template class called 'Target', as illustrated below
template<TargetType K, typename V = plat_target_handle_t>
class Target
{
.............
..............
};
TargetType is an enum data type.
template<>
template< TargetType T>
std::vector<Target<T> >
Target<TARGET_TYPE_X>::getChildren(const TargetState i_state) const
{
std::vector<Target<T> > l_children;
for ( int i=0; i < elements_in_some_list ; ++i)
{
/*If the current entry in some_list match my critera, add to the l_children */
}
}
TargetType is an enum data type and TARGET_TYPE_X is one of the enum values.
I want to move all the logic to select the children to a global method, lets say getChildrenHelper.
getChildrenHelper is declared as below.
void getGhildrenHelper(const TargetType i_targetType,
const TargetState i_targetstate,
std::vector<Target<TARGET_TYPE_ALL>> & io_children);
And then the getChildren method would eventually look like
template<>
template< TargetType T>
std::vector<Target<T> >
Target<TARGET_TYPE_X>::getChildren(const TargetState i_state) const
{
std::vector<Target<T> > l_children;
childHelper(T,i_state,l_children);
return l_children;
}
My guess is this cannot be done, though the native compiler that I am working with did not through an error.
However there is another existing code where the similar concept is working perfectly fine
template< TargetType K >
inline ReturnCode putParam(const Target<K>& i_target,
const RingID i_ringID,
const RingMode i_ringMode)
{
ReturnCode l_rc = FAPI2_RC_SUCCESS;
// Find the string in the SEEPROM
l_rc = findInImageAndApply(i_target, i_ringID, i_ringMode);
return l_rc;
}
fapi2::ReturnCode findImageAndApply(
const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
const RingID i_ringID,
const fapi2::RingMode i_ringMode)
{
................
................
}
It is quite common for template functions to invoke ordinary, non-template functions in order to execute a large chunk of code that does not need or use any template parameters. This is a common technique for avoiding template-generated code bloat.
In your case, TargetType appears is a template parameter, and there is no such class. As such:
void getGhildrenHelper(const TargetType i_targetType,
const TargetState i_targetstate,
std::vector<Target<TARGET_TYPE_ALL>> & io_children);
that by itself should not compile, since TargetType appears to be a template parameter, and not a class name, based on the code in your template specialization.
But, your code might be ambiguous, here. In any case, if neither TargetType and TargetState, nor Target<TARGET_TYPE_ALL> are template parameters, this would make this an ordinary function, and it can certainly be invoked from a template function, with matching parameters.
A template function can do anything that an ordinary function does, including calling other functions, or using other templates. The requirements are the same as for any other function: matching function parameter types, etc...
This is a very basic question and I'm sure this was answered before, but I don't know what to search for.
Stated I have a function that integrates a mathematical function:
double integrator(double (*func_to_integrate)(double,double));
But my function to integrate is of a type that allows me to manipulate more than two parameters, for example:
double func_to_integrate(double mu, double w0, double x, double y);
So that I can loop over different values of mu and w0 and compare the results of integration.
How can I pass a function like func_to_integrate to integrator?
Greetings
Edit: As alain pointed out in the comments this is partly a duplicate of: How can currying be done in C++?
Is there an elegant solution doing a currying operation on a function pointer?
Given you are able to change the signature of the integrator function, there are several solutions. The basic two directions are
use a general template parameter instead of the function pointer (--where the caller has to be aware of the correct signature to pass), or
use std::function<double(double, double)> as the function argument.
Both alternatives allow you to pass general function objects (functors, lambdas, a std::bind-object, etc.). I'd go with alternative 1. as it usually gives a better performance.
Then you can easily set up a lambda:
double mu = 1.0;
double w0 = 1.0;
auto f = [mu, w0] (double x, double y) { return func_to_integrate(mu, w0, x, y); };
and pass f to your (adusted) integrator routine.
Here is further an alternative if you cannot change the function signature -- as it is often the case for third-party libraries.
I first thought there is no solution in this case, as you can't bind a general functor to a function pointer. But then I encountered the nice idea in this answer (which I slightly adjusted): encode everything in terms of a static std::function variable, then use a static function to call this std::function object. As the static function is just syntactic sugar for a global function, it is possible to set up a function pointer to it:
template <typename Res, typename... Args>
struct function_ptr_helper
{
public:
template<typename function_type>
static auto bind(function_type&& f) { func = std::forward<function_type>(f); }
static auto invoke(Args... args) { return func(args...); }
static auto* ptr() { return &invoke; }
private:
static std::function<Res(Args ...)> func;
};
template <typename Res, typename... Args>
std::function<Res(Args ...)> function_ptr_helper<Res, Args...>::func;
template <typename Res, typename ... Args>
auto* get_function_ptr(std::function<Res(Args...)> f)
{
using type = function_ptr_helper<Res, Args...>;
type::bind(std::move(f));
return type::ptr();
}
DEMO
You can use it as
double mu = 1.0;
double w0 = 1.0;
std::function<double(double, double)> f
= [mu, w0] (double x, double y) { return func_to_integrate(mu, w0, x, y); };
integrator(get_function_ptr(f));
Be aware, however, that you are dealing with global variables here. This often works, but sometimes might lead to subtle errors (for example when you call get_function_ptr more than once in a single expression).
How can I pass a function like func_to_integrate to integrator?
Seems very easy to fix. Just add two more arguments to your pointer function signature.
double integrator(double (*func_to_integrate)(double,double,double,double));
As previous comments point out the most elegant solution would be using bind and or lambda. A nice solution would be an adapter design pattern class wrapper, where mu and w0 become class members.
class IntegratorAdaptor {
private:
double _mu, double _w0;
public:
IntegratorAdapter(double arg_mu, double arg_w0)
: _mu(arg_mu), _w0(arg_w0) { }
double twoArgIntegrator( double x, double y )
{ return func_to_intergrate( _mu, _w0, x, y ); }
};
Construction of this class is very low overhead, so I made the members immutable. I didn't come up with very good names for the class and functions, you should put more thought into those names than I did.
Most answers I've seen for this kind of question rely on std::function and/or C++ templates. I wanted to share an alternate solution which may be less general, but to me is simpler. It doesn't use std::function or templates---in fact, it doesn't use any libraries at all.
The idea is that instead of passing around a function pointer, you pass around an object that implements a particular 'interface'. In this example,
double integrator(double (*func_to_integrate)(double,double))
becomes
double integrator(Integratable func_to_integrate)
where Integratable is an 'interface' (abstract base class) defined as
class Integratable {
public:
virtual double compute(double x, double y) = 0; // pure virtual function
}
We can then make func_to_integrate into an instance of this class, with extra members for the additional parameters:
class SomeClassName : public Integratable {
public:
double compute(double x, double y);
double mu;
double w0;
}
SomeClassName func_to_integrate;
To test several values of mu and w0 in a loop:
for(double mu : mus) {
for(double w0 : w0s) {
func_to_integrate.mu = mu;
func_to_integrate.w0 = w0;
integrator(func_to_integrate);
}
}
Of course, we have to modify integrator so that instead of calling a function pointer, it calls the compute() method on the object passed to it, but this is trivial (assuming you can change the signature of integrator, which is probably required for any possible solution to this problem).
I like this solution because it avoids some of C++'s more heavyweight features and libraries. However, it certainly is less general than many of the other solutions that are often suggested for partial application in C++. For OP I believe this solution is an elegant fit for the given use case.
Hi I have a problem to compile my class in XCode, gcc(Apple LLVM compiler 3.0)
I wrote class ContextSchedule it means class which encapsulates list of other class member functions and have no problem to compile it under MSVC++ 2005.
template<class T>
class C_ContextScheduler
{
public:
typedef void (T::*T_EventFunc)();
typedef std::map<u64, T_EventFunc> T_EventMap;
public:
//# c-tor
C_ContextScheduler(T & context) : m_Context(context), m_currentTick(0) {};
//# Schedule
//# funcPtr - pointer to function of class T
//# dellayTime in milliseconds - after dellayTime from now will be funcPtr called
void Schedule(T_EventFunc funcPtr, u32 dellayTime)
{
u64 callingTime = m_currentTick + dellayTime;
std::pair<int, bool> res = m_eventMap.insert(T_EventMap::value_type(callingTime, funcPtr));
SC_ASSERT(res.second);
} ...
Any ideas? Want preserve template way of this solution, thnx.
When the compiler compiles this template, T is not yet known. Therefore the exact type of T_EventFunc and T_EventMap is also not yet known and that compiler doesn't know that T_EventMap::value_type will end up being a type. To make this clear, use the typename keyword:
... = m_eventMap.insert(typename T_EventMap::value_type(callingTime, funcPtr));
Since you don't supply the error you are getting, we can only guess. And my guess is that the result of your insert-call is not correct.
According to this refernce, the return value of std::map::insert is std::pair<iterator, bool>. Are you sure the iterator is an int?
This is very likely an extremely basic question - sorry about that.
I have written an interface in C++ which is powered by a C engine. One of the C-engine functions has the following signature:
static int f(double t, double *y, double *ydot, void *data)
The *data thingy is to pass user data to an ODE solver. Now, in C I would simply create an struct, initialize it with my data, and pass it around. In C++ I want to create a class containing the user data, and pass it as I previously passed the struct. This can be done, as structs are classes.
However, when I try to do it, the following happens:
int.cpp:25: error: no matching function for call to ‘UserData::UserData()’
int.cpp:13: note: candidates are: UserData::UserData(double)
int.cpp:5: note: UserData::UserData(const UserData&)
int.cpp:28: error: ‘void*’ is not a pointer-to-object type
int.cpp:29: error: ‘void*’ is not a pointer-to-object type
My questions are the following:
What does the void *data notation mean?
Why is it complaining that I don't have a constructor with the appropriate signature?
Obviously I am very much a rookie, so I'm sorry if this is very obvious, but I don't even know what terms to use to google the problem (in addition to googling the error itself).
Thanks!
Edit:
I apologize for the vagueness of the previous question. Also, I solved the problem and it was a very stupid mistake.
I had a class containing parameters:
class Data{
// an interface to get parameters
};
and I needed to call a C function with the signature
static int f(double t, ...., void *user_data)
I mistakenly did this:
static int f(double t, ...., void *user_data){
Data *data = (Data*) data; /* this is the stupid mistake */
}
When I meant to do this (now it works):
static int f(double t, ...., void *user_data){
Data *data = (Data*) user_data; /* this is the correction */
}
Thank you all - and I appreciate indicating the correct meaning of void *data.
void *data
means a pointer to any address. It is a non-typesafe way of passing data of arbitrary type. It is a common pattern in C to implement what would be done with a function object in C++. The data parameter is probably not actually used by your ODE solver, but by a callback that you are providing. You and the callback need to know the what data points to, the ODE solver doesn't. The solver just passes the address to the callback function.
As simple example, suppose the library had a function to find the root of a function in a single variable
typedef double (*valuation_function) (double x, void * params);
double find_root(valuation_function fn, double lower, double upper, void* params);
The params function gives you the ability to write a parameterized function. Suppose you wanted to find the root of a line.
struct Line {
double slope;
double intercept;
public:
Line(double s, double i) : slope(s), intercept(i) {}
};
double a_line(double x, void *params) {
Line* line = (Line *)params;
return line->slope * x + line->intercept;
}
You could then call the function find_root for any line.
Line fortyFive(1.0, 0.0);
find_root(a_line, fortyFive);
You can look at the gsl library for more examples.