Build error: base specifier must name a class - c++

I am trying to build a big project in Mac OS X with cmake and ran into following error which i am unable to solve.
Archive.hpp:92:30: error: base specifier must name a class
struct Derived : T, Fallback { };
Code:
template<typename T>
class has_save_func
{
struct Fallback { int save; }; // add member name "X"
struct Derived : T, Fallback { };
...
Furthermore i have following:
Archive.hpp:137:13: error: type 'unsigned long' cannot be used prior to '::'
Code:
template <class A>
static bool save(const A& data, class OutputArchive& oarchive, const std::string& id, typename boost::enable_if_c<has_save_func<A>::value, A>::type* def=NULL){
// todo check if A actually is friend with Access class, else return false
A::save(data, oarchive); // ! Error on this line !
return true;
}
template <class A>
static bool save(const A& data, class OutputArchive& oarchive, const std::string& id, typename boost::disable_if_c<has_save_func<A>::value, A>::type* def=NULL){
// todo check if A actually is friend with Access class, else return false
return serialization::save<A>( data, oarchive, id);
}
Code calling (OutputArchive.hpp):
template<class T>
void write(const T& data, const std::string& id){
// the data method must have an implementation of load/save and if not then we try the generic write
// method which could provide a solution by the implementation itself
writeEnterScope(id);
try {
Archive::Access::save<T>(data, *this, id);
} catch (...){
// we fall back to this call
boost::any adata(data);
write(adata, id);
}
writeLeaveScope(id);
}
Code serializeutil.cpp
void save(const rw::math::Q& tmp, OutputArchive& oar, const std::string& id){
oar.write(tmp.size(), "size");
for(int i=0;i<tmp.size();i++){
oar.write(tmp[i],"q");
}
}
Could it be a problem with the compiler im using?

Both errors point to the same: you are trying to use your templates with a non-class, most probably unsigned int. In the first case, you would be trying to have Derived inherit from unsigned int, which is illegal; in the second, you would be trying to call a static method (save()) on unsigned int, which is illegal again. Looking at the code calling the templates would clarify the issue.
UPDATE: From the information added to the question we can now conclude that this was indeed the case. tmp.size(), is most probably an unsigned int, so you are calling oar.write() with an unsigned int; this, in turn, calls save() with an unsigned int, so it tries to call unsigned int::save(), which is illegal, and instantiate class has_save_func<unsigned int>, which tries to define struct Derived : unsigned int, Fallback which is illegal again.
I'm afraid you will need to redesign your classes if you want them to work with built-in types, such as unsigned int. You might do a complete redesign or just overload functions write() or save(), depending on what you have available.

I think that i may be responsible for the mentioned pieces of code. Something is missing though, and multiple persons already noticed this. The overloaded write functions on the OutputArchive which currently looks something like this:
virtual void writeEnterScope(const std::string& id) = 0;
virtual void writeLeaveScope(const std::string& id) = 0;
virtual void writeEnterArray(const std::string& id) = 0;
virtual void writeLeaveArray(const std::string& id) = 0;
// writing primitives to archive
virtual void write(bool val, const std::string& id) = 0;
virtual void write(int val, const std::string& id) = 0;
virtual void write(unsigned int val, const std::string& id){ write((int)val,id); }
virtual void write(boost::uint64_t val, const std::string& id) = 0;
virtual void write(double val, const std::string& id) = 0;
virtual void write(const std::string& val, const std::string& id) = 0;
The serialization part of the software was not supposed to be used yet, but it ended up in the build system anyways. If you comment out the serialize directory in CMakeLists.txt in src/rwlibs then it should work. Or add a write function for an unsigned long:
virtual void write(unsigned long val, const std::string& id){};
And yes, i did look into Boost.Serialization before venturing into creating yet another serialization framework. I was however trying to create something that would be less intrusive, less templated and more user friendly.... Guess i failed at that...

First, it would be better to use existing solution like Boost.Serialization. It's already debugged and works in all the cases you may need.
However, you should still know where your current code has problems and how to do template machinery like this. So:
oar.write(tmp.size(), "size");
^^^^^^^^^^
This is unsigned int. And you do need to serialize it. So you need a write, that can accept primitive types. There are two options:
Write non-template overloads for primitive types. Non-template overloads have priority over template ones, so if you write explicit non-template overload with unsigned int first argument, the template won't be instantiated and there won't be any error. You will however need overloads for each possible primitive type separately, because template that matches exactly will be still preferred over non-template overload that requires conversion.
Use free save function instead of method. Advantage of method is that it can be virtual, but you don't usually need that with template. Advantages of free function are that they can be defined for non-class types and that they can be defined for already existing classes, both of which you often do need in templates. So you would change all instances of the save method to free function, drop the has_save_func altogether and overload the save function for primitive types you need.
Amend the has_save_func with check whether the template argument is a class type. Non-class types don't have methods, so that's what the other variant will do. You can either use the boost::is_class or implement something similar. Boost actually implements it by enumerating all the other options, but it can also be implemented using pointer-to-member, which will cause SFINAE when given non-class type. Unfortunately you don't have anything to cause SFINAE when given class type, so you have to combine with function templates and sizeof and end up with really tricky stuff (I'm sure I've seen it, but really don't remember it).

Related

Convert int into a generic template type

I have the following function in TreeWrapper.h:
template<typename Key, typename Data, class Compare=std::less<Key>>
class TreeWrapper{
// .............
public:
void addNode(Key &key, Data &data) {
currentAVLTree.addNode(key, data);
}
I would like to use the following command:
currentGroup.addNode(group, group.getTotal());
But getTotal returns int and not Data. Is it possible to convert it somehow? I thought that Data is a generic type that get anytype. Why it does not work?
EDIT:
In TreeWrapper.h the important part:
template<typename Key, typename Data, class Compare=std::less<Key>>
class TreeWrapper {
AVLTree<Key, Data, Compare> currentAVLTree;
public:
void addNode(Key &key, Data &data) {
currentAVLTree.addNode(key, data);
}
};
In the AVLTree.h:
template<typename Key, typename Data, class Compare=std::less<Key>>
class AVLTree {
Compare keyCompare;
AVLNode<Key, Data> *root;
int length;
public:
bool addNode(Key &key, Data &data) {
// impl
}
};
In the GroupWrapper:
class GroupWrapper {
private:
TreeWrapper<Group, Group, compareGroup> currentGroup;
public:
void addGroup(Group group) {
currentGroup.addNode(group, group.getTotal());
}
};
But I get an error: Parameter type mismatch: Expression must be lvalue on group.getTotal() and it suggests to change Data to int. Why?
I thought that Data is a generic type that get anytype.
Not quite. It is true that Data represents a generic type, but that view holds only when defining the template. When a template is used, it is instantiated. Part of instantiation involves providing concrete replacements for the generic template parameters. For that instantiation, the replacement is fixed, no longer generic.
For example, look at the declaration of your TreeWrapper template.
template<typename Key, typename Data, class Compare=std::less<Key>>
class TreeWrapper
One way to use and instantiate this template is with a line like:
TreeWrapper<Group, Group, compareGroup> currentGroup;
Effectively, this takes the TreeWrapper template and replaces every instance of "Key" with "Group", every instance of "Data" with "Group", and every instance of "Compare" with "compareGroup". The result is the definition of the type of currentGroup.
Consequentially, the signature of addNode becomes the following:
void addNode(Group &key, Group &data)
You can try to call currentGroup.addNode(group, group.getTotal()), but since getTotal() returns an int (not convertible to Group &), the signature does not match.
A solution for (just) this call is the suggested change of Data's concrete replacement. If you were to use
TreeWrapper<Group, int, compareGroup> currentGroup;
then the signature of addNode would be
void addNode(Group &key, int &data)
and the call to currentGroup.addNode(group, group.getTotal()) would almost* match. However, this would presumably mess something else up, unless you had decided to use Group as the tree's data type without understanding what type of data the tree would hold.
* "Almost" because this would bind a temporary to a non-const reference. Since addNode sounds like it has no business changing either of its parameters, they should be constant references (or non-reference values), which would then make your call work.
void addNode(const Key &key, const Data &data)
This should be done in both TreeWrapper and AVLTree.
You are passing non-const reference, which is why it complains about lvalue, which means a value which can be on the left side of an assignment. A function call needs to return a reference if you want to put it on the left side, and yours returns just plain int.
Changing getTotal to return a reference would probably be a very bad idea, so two solutions remain.
Add const at least for data:
bool addNode(Key &key, const Data &data)
Or pass a value:
bool addNode(Key &key, Data data)
Consider same changes for key.

Templates without T parameters in a non-template class

Ok, I read a lot of answers here and there about this problem, but probably since I don't know the proper syntax I can't figure out how to do this.
I have a non-template class which has to implement different static utility functions, mainly for serialization and deserialization. What I currently have is something like this:
class Data_Base : public QObject
{
...
protected:
static QByteArray Serialize(int value);
static int DeserializeInt(QByteArray ser);
static QByteArray Serialize(char *value);
static char *DeserializeCharArr(QByteArray ser);
static QByteArray Serialize(QString value);
static QString DeserializeQString(QByteArray ser);
....
}
Now, I'd prefer to have all the Deserialize* function as a template, since it will be nicer. And as a bonus, have also the Serialize functions as templates, so I will force the user to actually explicitely say which overload to call. Something which can be used this way:
QByteArray ba = Serialize<int>(5);
...
int theValue = Deserialize<int>(ba);
Now, I've tried different approaches, but since all the functions I saw only examples implementing the templates automatically and not one overload at a time I couldn't find out how to make this work.
Of course this is C++, with QT additions.
As stated in the comments, it is called template specialization and looks like this:
class X
{
public:
template<typename T>
static QByteArray Serialize(T const& t);
template<typename T>
static T Deserialize(QByteArray& v);
};
template<>
QByteArray X::Serialize(int const& t)
{
/* ... */
}
template<>
QByteArray X::Serialize(QString const& t)
{
/* ... */
}
template<>
int X::Deserialize(QByteArray& v)
{
/* ... */
}
template<>
QString X::Deserialize(QByteArray& v)
{
/* ... */
}
QByteArray x=X::Serialize(5);
int y=X::Deserialize<int>(x);
When using Serialize you do not need to specify the template parameter because it can be deduced from the argument's
type.
But you cannot deduce by return type, so you need to add the template parameter when using Deserialize.
IMO force your solution with the usage of template specialization could be a bad choice design.
As I've already said in a comment, templates are generally good when your code structure is equal for each data type.
Serialization is a delicate operation (casting, raw memory, etc.) and data structure can define different implicit conversions and produce an UB.
If I had to implement an a "template" behaviour, this would be the first solution (just a scratch!):
struct Foo {
// Some data member variables.
std::string m_nopod;
// Serialize data object. 'It' must to be a output iterator
template<typename It>
void serialize(It out_iterator) {
constexpr size_t BYTES_FOR_SIZE = sizeof(decltype(m_nopod.size()));
constexpr size_t BYTES_FOR_CHAR = sizeof(decltype(m_nopod)::value_type);
// size definitions.
const auto len_str = m_nopod.size();
const auto len_data = BYTES_FOR_CHAR * len_str;
// Temporary memory buffers.
uint8_t memory_size[BYTES_FOR_SIZE];
auto memory_data = std::make_unique<uint8_t[]>(len_data);
// Raw bytes copy.
std::memcpy(memory_size, &len_str, BYTES_FOR_SIZE);
std::memcpy(memory_data.get(), m_nopod.data(), len_data);
// write with the iterator.
for (size_t i = 0; i < BYTES_FOR_SIZE; ++i) {
*out_iterator = memory_size[i];
}
for (size_t i = 0; i < len_data; ++i) {
*out_iterator = memory_data[i];
}
}
};
Where the out_iterator must to be a output_iterator, and ::value_type must to be a implicit convertible type to unsigned char.
The function can be invoked with different data structures (containers):
int main(int argc, char *argv[]) {
std::vector<char> memory_buffer_char;
std::vector<int> memory_buffer_int;
std::string memory_buffer_str;
Foo foo{"a_string"};
foo.serialize(std::back_inserter(memory_buffer_char));
foo.serialize(std::back_inserter(memory_buffer_int));
foo.serialize(std::back_inserter(memory_buffer_str));
return 0;
}
As I've already said, however, I'll never adopt that solution. Rather I'm going to use a simple overloading of function for those various types.
In order avoid writing same thing more than once, I'll define a unique helper function (a private method) which contains the logic of the class.
For example the helper function could create an ordinary buffer of memory in which to serialize the class (array of char) and then overloaded functions should only adapt that array in the proper input data structure.
In that way when the class logic (e.g., data members) changes, you should modify only the helper function.

Can I define implicit conversion from std::function to std::shared_ptr<MyClass>?

I have a class that works as a predicate to select value from list.
class Predicate {
public:
// In this example, I am using QString as value type
// this is not what happens in actual code, where more complex data is being validated
virtual bool evaluate(const QString& val) const = 0;
};
Originally, I used lambda functions but this created lot of repetitive garbage code. So instead, I want to use predicate classes that use inheritance. For example:
class PredicateMaxLength: public RowPredicate {
public:
PredicateMaxLength(const int max) : maxLength(max) {}
virtual bool evaluate(const QString& val) const {return val.length()<maxLength;}
protected:
const int maxLength;
};
To allow inheritance do it's deed, pointers are given rather than values:
class SomeDataObject {
// Removes all values that satisfy the given predicate
int removeValues(const std::shared_ptr<Predicate> pred);
}
Now we are surely stil going to use lambdas in cases where code would not be repetitive (eg. some special case). For this purpose, PredicateLambda has been created:
typedef std::function<bool(const QString& val)> StdPredicateLambda;
class PredicateLambda: public Predicate {
public:
PredicateLambda(const StdPredicateLambda& lambda) : RowPredicate(), callback_(lambda) {}
virtual bool evaluate(const QString& val) const override {return callback_(val);}
protected:
const StdPredicateLambda callback_;
};
The nasty effect of this is that whenever lambda is used, it must be wrapped into PredicateLambda constructor:
myObject.deleteItems(std::make_shared<PredicateLambda>([]->bool{ ... lambda code ... }));
This is ugly. I have two options:
for every function that accepts predicate, have an overload that does the conversion seen above. This duplicates number of methods in header file
Have an implicit conversion from std::function<bool(const QString& val)> to std::shared_ptr<Predicate> which would execute this:
std::shared_ptr<Predicate> magicImplicitConversion(const StdPredicateLambda& lambdaFn) {
return std::make_shared<PredicateLambda>(lambdaFn);
}
I came here to ask whether the second option is possible. If it is, does it carry any risk?
If you don't want to use template to not expose code, you may use std::function:
class SomeDataObject {
// Removes all values that satisfy the given predicate
int removeValues(std::function<bool(const QString&)> pred);
};
and your predicate
class PredicateMaxLength {
public:
explicit PredicateMaxLength(int max) : maxLength(max) {}
bool operator ()(const QString& val) const {return val.length()<maxLength;}
protected:
int maxLength;
};
So you can use either
SomeDataObject someDataObject;
someDataObject.removeValues(PredicateMaxLength(42));
someDataObject.removeValues([](const QString& s) { return s.size() < 42; });
You want polymorphism, and you don't want to use template-style header lambdas. And you want to be able to have a few default cases.
The right answer is to throw out your Predicate class.
Use using Predicate = std::function<bool(const QString&)>;.
Next, note that your Predicate sub-types are basically factories (the constructor is a factory) for Predicates with some extra state.
For a std::function, such a factory is just a function returning a Predicate.
using Predicate = std::function<bool(const QString&)>;
Predicate PredicateMaxLength(int max) {
return [max](QString const& str){ return val.length()<max; }
}
where the body of PredicateMaxLength goes in a cpp file.
If you have an insanely complicated set of state for your Predicate-derived class, simply give it an operator() and store it within a std::function. (In the extremely rare case that you have some state you should store in a shared ptr, just store it in a shared ptr).
A std::function<Signature> is a regular type that is polymorphic. It uses a technique known as type erasure to be both a value and polymorphic, but really you can call it magic.
It is the right type to use when you are passing around an object whose only job is to be invoked with some set of arguments and return some value.
To directly answer your question, no, you cannot define a conversion operator between a std::function and a std::shared_ptr<yourtype> without making your program ill formed, no diagnostic required.
Even if you could, a std::function is not a lambda, and a lambda is not a std::function. So your conversion operator wouldn't work.

Less writing for type conversion possible?

Let's assume you loaded a dynamic library using dlopen() or LoadLibrary() on Windows, and you want to get a symbol from it and cast it to a specific function type. It is so unbelievable redundant to write the type twice!
void (*Test)(int, float) =
reinterpret_cast<void (*Test)(int, float)>(dlsym(handle, "Test"));
I want the code to be compilable without the C++11 standard, therefore the auto keyword is not an option. I tried using templates because compilers can often detect the template parameters from the given parameters, but it does not seem to work for the type of the assignment value.
template <typename T>
T GetSym(void* handle, const char* symbol) {
return (T) dlsym(handle, symbol);
}
void (*Test)(int, float) = GetSym(handle); // does not compile
Is there a way to bring less redundancy into the code? When retrieving a huge number of functions from a dynamically loaded library, it is awful to write each and every cast twice!
You can do this with an evil templated conversion operator.
struct proxy {
public:
proxy(void* ptr) : ptr(ptr) {}
template <typename T>
operator T() const {
return reinterpret_cast<T>(ptr);
}
private:
void* ptr;
};
proxy GetSym(void* handle, const char* symbol) {
return proxy(dlsym(handle, symbol));
}

Template classes C++ / Qt

I have an application which will be receiving messages from another application. These messages will be XML fomatted strings, and they will contain a <messageType> tag. The message type will identify this message as a type of internal message. The following code shows my internal message structures.
namespace
Application1{
enum ApplicationAttributes{
ApplicationName = 1000,
Start,
Stop,
Pause,
Save,
Discard,
SelectRunway,
DoAlignment,
RedoAlignment,
AlignmentOK,
DoCalibrationStage1,
SetCalibrationStage1,
SetCalibrationStage2,
SetCalibrationStage3,
CancelCalibration,
CalibrationOK
};
struct Alignment{
int x;
int y;
int error;
};
struct Calibration{
int x;
int y;
int error;
};
}
alignment and calibration are the two internal message structures.
What I'm trying to do is build a 'message interpreter' which will receive an XML string, decode it and return any one of the structs shown above; so if the <messageType> is 'alignment', the message interpreter will build an alignment struct, and return that.
So ultimately, I'm trying to make a template function, which can return an arbitrary struct, based on what i read in from <messageType>.
Are my objectives clear? is my approach the right one?
Let me know if I should clarify, or if I should take a different approach.
I don't believe a template function makes sense. Your input is always going to be a string, and C++ can't differentiate function signatures based on return type alone - so I don't know how a template would help - what would the type argument be?
I'd suggest making your function a normal one that parses out the messageType and allocates a struct based on it - you can use whatever constructs you want for this.
The trick would be (in my mind) to derive all of your internal-message-classes from the same empty base class - you could then return a pointer to that base class back from your function, and it will hold whatever type got created.
It be a good idea to return an enumeration along with the pointer in a std::pair which you can use to determine the correct derived type that was created, that way you can cast the result directly to the correct derived type with a static_cast.
As I understand it your structures are known within the application, so what about this save variant:
class Message {
public:
static Message Alignment (alignment_t const &);
...
Type type() const;
int alignment() const;
private:
Message (Type t);
assert_type (Type t, const char *msg) const;
private:
Type type_;
};
Message Message::Alignment (alignment_t const &alignment)
{
Message ret (Type::Alignment);
ret.alignment_ = alignment;
return ret;
}
void Message::assert_type (Type t, const char *msg) const
{
if (type() != t) throw std::runtime_error (msg);
}
int Message::alignment() const
{
assert_type (Type::Alignment,
"alignment_x() called for non-alignment-message");
return alignment_;
}
(coded without verification to give you the idea)
This works without polymorphism (I use this pattern in a compiler for a LISP like language, where polymorphic trees would result in more complicated code). You can change it to return "alignment_x()" and so on, if you like that more.
Fully dynamic structures are not possible, and solutions that try to come near will be rather complicated. Use the most-maintainable solution.
If you write a factory function/functor for each type, you can associate that with the messageType (map<string, Factory*> will be sufficient), but what to return?
You can return some kind of discriminated union, or boost::variant, if you don't mind the top-level decoder depending on all possible message types.
But, what is the decoder going to do with this return value? If it just switches on the type and calls a type-specific callback in each case, you could invert control by attaching a callback function/functor to the factory directly.
Then the decoder doesn't return anything, it just constructs the message struct and passes it directly to a handler.
Simple implementation (OK, that was more typing than I thought):
class Decoder
{
public:
virtual ~Decoder();
virtual void decode(std::string const &xml) = 0;
};
template <typename Factory, typename Callback>
class SimpleDecoder: public Decoder
{
Factory factory;
Callback callback;
public:
SimpleDecoder(Factory f, Callback c)
: factory(f), callback(c)
{}
void decode(std::string const &xml)
{
callback( factory( xml ) );
}
};
std::map<std::string, Decoder*> factories;
template <typename F, typename C>
void registerSimpleDecoder(std::string const &n, F f, C c)
{
factories[n] = new SimpleDecoder(f, c);
}
void decodeXmlMessage(std::string const &messageType, std::string const &body)
{
factories[messageType]->decode(body);
}
using QMetaObject::newInstance, so you can create a QObject* that can be converted afterwards to your class using dynamic_cast
class MyClass : public QObject{
public:
enum Type{ MyClassType = UserType + 1 }
Q_INVOKABLE MyClass();
}
Q_DECLARE_METATYPE ( MyClass )
then, in your XML Parsing Code:
MyClass* myObject = (MyClass*) QMetaType::construct ( MyClass::MyClassType );
And things will work out.