A class MessageBase has a public template member function like this:
/*! Get a pointer to a field. Inplace, 0 copy.
\tparam T type of field to get
\return pointer to field or 0 if not present */
template<typename T>
const T *get() const
{
Fields::const_iterator fitr(_fields.find(T::get_field_id()));
return fitr == _fields.end() ? 0 : &fitr->second->from<T>();
}
When I declare a pointer to a type T (in this case TEX::MDEntryPx)
const TEX::MDEntryPx *price = me->get();
then try to access the function, clang++ come back with
main.cpp|338|error: no matching member function for call to 'get'
I am not using the correct syntax but not sure what it is?
Duh,
const TEX::MDEntryPx *price = me->get<TEX::MDEntryPx>();
Related
I am currently trying to make a Hash table template function and then adapt a password server class on top of it. I've run into a problem when trying to adapt the password server class to the hash table template. When I try to call a function from the template:
PassServer::PassServer(size_t size) : passwords(size)
{
HashTable<std::string, std::string>::HashTable(size);
}
it keeps giving me an error "Qualified name refers into a specialization of variable template 'HashTable'" and I have no idea how to solve this. I've added a specialization for the constructor yet it doesn't seem to change anything. This is the constructor I'm trying to adapt:
template <typename K, typename V>
HashTable<K, V>::HashTable(size_t size = 101)
{
theHash.resize(prime_below(size));
currentSize = 0;
}
with the specialized constructor:
template<>
HashTable<std::string, std::string>::HashTable(size_t size = 101)
{
theHash.resize(prime_below(size));
currentSize = 0;
}
but it still gives the same error
Here's my code:
class Patient {
public:
const int patientId;
const PatientKind kind;
const bool hasInsurance;
std::vector<ProcedureKind> procedures;
Patient(int, PatientKind, bool);
bool addProcedure(const ProcedureKind procedure);
double billing();
virtual double liability() = 0;
};
class Hospital {
public:
Patient &addPatient(const PatientInfo &);
};`
I don't know how to write:
Patient &Hospital::addPatient(const PatientInfo &)
{
}
Whatever I try to return or pass as argument gives me an error... Also, I don't understand what is this function expecting as an argument with just &?
Any kind of help / insight will be appreciated :D
Seems like you're trying to implement a header definition someone else wrote. That & means that the function expects a reference to an instance of PatientInfo. In the implementation, the only thing you have to do is to give the parameter a name like so:
Patient& addPatient(const PatientInfo& info)
{
// do whatever you need with 'info'
}
You can read more about c++ function declaration and implementation in any basic c++ text.
I used template template parameter as follows:
/* [1]: Definition containing a template template parameter */
template <typename T, template<class> class Kernel>
void ForEach(Kernel<T> kernel, T * pSrc, int elementCount) {
//....
}
/* [2]: Definition of a helper struct */
template <typename T> struct KernelStd {
//...
};
/* [3]: Use the previous definitions */
float arr1[5] = {1,2,3,4,5};
//The following two calls to ForEach do successfully compile
ForEach(KernelStd<float>(), arr1, 5); //USE1
ForEach<float>(KernelStd<float>(), arr1, 5); //USE2
/* [4]: Definition of a helper function */
template <typename F, typename ...Args>
void forwarder(F func1, Args && ...args) {
//...
func1(std::forward<Args>(args)...);
}
//But the following callS do not compile.
forwarder(ForEach, KernelStd<float>(), arr1, 5); //USE3
forwarder(ForEach<float>, KernelStd<float>(), arr1, 5); //USE4
I am using VS2013 update 5 and I get the following error:
error C2783: 'void ForEach(Kernel<T>,T *,int)' : could not deduce
template argument for 'Kernel'
Any help will be appreciated.
forwarder is a function, so its first argument must be an entity (object or function) of type F.
ForEach is neither a function nor an object, it's a template. You therefore cannot pass ForEach to forwarder.
ForEach<float> does not pass enough template arguments to fully identify a function instantiated from the ForEach template. You can get away with it when calling the function template because of template argument deduction. But in the context of forwarder, the type F is supposed to be deduced from the first argument, so you have a bit of a chicken-and-egg problem.
If you want to use forwarder, you must supply it with an actual function, not with a template. So you'd have to do this:
forwarder(ForEach<float, KernelStd>, KernelStd<float>(), arr1, 5);
ForEach<float, KernelStd> contains all template arguments and it therefore designates a function (instantiated from a template).
I have a list of functions that are put in a table for lookup for an interpreter. I cast each function to void (*) () as follows:
using vptr = void (*) (); // cast to a function that takes no args, and returns no result
struct function date_funs[] =
{
{C_FN3, X_A3, "III", (vptr) do_hms_to_time, "hms_to_time"},
...
This works, and does exactly what I want. I wonder if there was another way of expressing it, like:
using vptr = reinterpret_cast<void(*) ()>;
The C++ compiler complains of a syntax error, though. Is there any way I can fix this, or should I just use the first form of vptr that I devised?
No.
using (in this context) defines a type alias. In your attempt, you are not giving a type, but have a partial expression, which is a syntax error.
To shorten usages, e.g. reinterpret_cast<void(*) ()>(do_hms_to_time), you could introduce a function as well as the using.
using vptr = void (*) ();
template <typename Func>
constexpr vptr to_vptr(Func && func)
{ return reinterpret_cast<vptr>(func); }
and use it
{C_FN3, X_A3, "III", to_vptr(do_hms_to_time), "hms_to_time"},
Maybe I'm seriously missing something, but I'm unable to get rid of a syntax problem with all my classes.
Here is an example :
class Foo {
bar: (x: string, y: number) => string = (xx: string, yy: number) : string => {
// do some stuff...
};
}
Since I'm enforcing type declarations using tslint, ALL my methods are written like this. It's horrible. Having to copy paste the arguments part, renaming the args names between the type declaration and the lambda declaration is soooo painfull.
So : is there a better way to combine type signature and lambda declaration without all the knee jerking ? I sincerely hope I have missed something and hope this is not "by design" ! :)
You need to configure TSLint to enforce types but ignore the type of the functions:
typedef enforces type definitions to exist. Rule options:
"call-signature" checks return type of functions
"parameter" checks type specifier of function parameters
"property-declaration" checks return types of interface properties
"variable-declaration" checks variable declarations
"member-variable-declaration" checks member variable declarations
You can use a file like this one to configure TSLint. And read this to learn more about how to configure it.
Edit:
If you're targeting ES5, you can also do something like this:
var bar = (x: string, y: number) : string => {
// do some stuff...
};
class Foo {
get bar () { return bar; }
}
var test = (new Foo).bar('hello', 3);
Or:
class Foo {
get bar () {
return (xx: string, yy: number): string => {
// do some stuff...
};
}
}
This way the method's context is preserved and it also exists on the prototype. There's also no need to copy the argument types, TSC will infer them.