error: Qualified name refers into a specialization of variable template - c++11

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

Related

C++: convert not from obj1 to obj2, but from obj1* to obj2?

A constructor for MyClass takes a pointer to another such object.
The C++ MyClass is functionally the same as a C "class" based on a typedef'd struct called MyType_T. (The C++ class is basically a wrapper to the old C code.) I'd like to be able to pass in a MyClass* anywhere I could pass in a MyType_T* before.
I'd like to write an automatic conversion of any MyClass* to MyType_T*, but I guess what's throwing me is that my type converter is written to take a MyClass not a MyClass*. Even though I'm sure that's the problem, I can't think of what syntax would solve it. I've thought about making a friend implementation of the cast, but I can't put it before the definition of class MyClass because it won't know the offset of thing. And I can't put after the definition of class MyClass because the MyClass constructor wants to use that conversion.
typedef struct MyStruct {
int iFoo;
struct MyType* ptypeParent;
} MyType_T;
void MyTypeCreator( MyType_T* ptypeSelf, int iFoo_in, MyType_T* ptypeParent );
class MyClass {
public:
MyClass( int iFoo, MyClass* pclassParent ) {
MyTypeCreator( &thing, iFoo, pclassParent ); <--------------- PROBLEM
MyTypeCreator( &thing, iFoo, &pclassParent->thing ); <------- WORKS
};
operator MyType_T*() { return &thing; } <---------------- INCORRECT: attempts to convert MyClass, not MyClass*, to MyType_T*.
MyType_T thing;
};
QUESTION 1: how to write a convertor from MyClass* instead of MyClass?
QUESTION 2: how can such a convertor check for NULL input? (If thing isn't offset of 0, but say 8, then converting from a NULL pclass without a check would give a value of 0x00000008, not NULL...)

How to call a class function which only argument is &

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.

C++, getting name of the plugin from derived class

I have a requirement wherein, I need to create a base class which will have some pure virtual functions which would be implemented by derived classes. These virtual functions are not enough and I also need to get the name of the plugin to be given to a library from the base class which I will create.
I am using factory pattern. Basically thought that based on the plugin name I would create the instance of that particular derived class.
But, the problem here is since I am using factory pattern, until I send plugin name I would not create object and until object is created plugin name would not be known. Because of this I always see empty plugin name.
Many plugins would be derived from this common base class, it's important to know name of the plugin at runtime.
Please suggest
You need to register a factory for each plugin type in your central factory.
struct common_args {
int width; // whatever
};
struct BasePlugin {
virtual ~BasePlugin() {}
virtual std::string get_name() const = 0;
virtual void do_stuff() = 0;
};
using single_type_factory = std::function<std::unique_ptr<BasePlugin>( common_args ) >;
using plugin_factory = std::function<std::unique_ptr<BasePlugin>( std::string name, common_args ) >;
struct central_factory:plugin_factory {
central_factory(central_factory&&)=delete;
central_factory():
plugin_factory(
[this](std::string name, common_args args)
->std::unique_ptr<BasePlugin>
{
auto it = m_factories.find(name);
if (it == m_factories.end())
return {};
return (*it)(args);
}
)
{}
void register_plugin_type( std::string name, single_type_factory f ) {
m_factories[name] = f;
}
private:
std::unordered_map<std::string, single_type_factory> m_factories;
};
that is just a sketch.

C++11 forwarding Template template parameter does not work

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).

Boost posix time

I have a very strange problem now.
class Message
{
Field time;
void SetTimeStamp()
{
time.dataTimeValue = &boost::posix_time::microsec_clock::universal_time();
}
void SetOtherFields()
{
}
};
class Field
{
boost::posix::ptime* dateTimeValue;
};
int main()
{
Message myMessage;
myMessage.SetTimeStamp();
myMessage.SetOtherFields();
}
When I call myMessage.SetTimeStamp(), I can set the TimeStamp correctly, I can see the address of dateTimeValue and the Value makes sense. But after that, I call myMessage.SetOtherFields(), the dateTimeValue pointer still points to the same memory which is good, but the value in that memory changes to a carzy number. I don't know what happened.
A decent compiler should have warned that the code is taking address of temporary. The microsec_clock::local_time() function returns ptime by value, resulting in Message::SetTimeStamp storing the address of the temporary into Field::dateTimeValue. Trying to access the values of the memory will result in undefined behavior.
To resolve this, consider changing Field to aggregate a boost::posix::ptime member variable, rather than a pointer.
class Field
{
public:
boost::posix_time::ptime dateTimeValue;
};
class Message
{
public:
Field time;
void SetTimeStamp()
{
time.dataTimeValue = boost::posix_time::microsec_clock::universal_time();
}
};

Resources