Nested vectors in Linux - c++

I'm trying to implement a DivideAndConquer template. The original project was in VisualStudio 2013, but when I move the source code to Linux I get errors.
#pragma once
#include <vector>
using namespace std;
template <typename Element>
class DivideAndConquer
{
public:
~DivideAndConquer(){}
vector<Element> solve(vector<Element> p);
protected:
virtual bool isSimple(vector<Element> p) = 0;
virtual vector<Element> simplySolve(vector<Element> p) = 0;
virtual vector<vector<Element>> decompose(vector<Element> p) = 0;
virtual vector<Element> combine(vector<vector<Element>> p) = 0;
};
The error reads DivideAndConquer.h:28: error: a function call cannot appear in a constant-expression. I have comments in my version, so line 28 is the declaration of the decompose function. There are similar errors for all declarations involving nested vectors across all other .h files.
Does Linux allow nested vectors in this fasion? I really don't want to keep track of an array's size throughout my whole implementation.

You are blaming linux for your minor mistake...
virtual vector<vector<Element>> decompose(vector<Element> p) = 0;
This should be :-
virtual vector<vector<Element> > decompose(vector<Element> p) = 0;
>> should be separated > >

Related

What causes the error #18 expected a ")" on a MSP430

Compiling the following C++14 code for a MSP430 using TI Code Composer I got the following errors:
subdir_rules.mk:14: recipe for target 'main.obj' failed
"Interface.h", line 75: error #18: expected a ")"
"Derived.h", line 91: error #18: expected a ")"
This is for the following code structure in which the Interface.h class is a library which compiles fine for STM32 targets.
#include <cstdint>
namespace NS
{
class Interface
{
public:
// Other pure virtual functions such as:
virtual void advance() = 0;
// This is the problem function
virtual void advance(const uint32_t N) = 0;
};
}
Next in the MSP430 project the interface is used in multiple objects. This is one example of multiple implementations, they all give the same error.
#include "Interface.h"
class Derived : public ::NS::Interface
{
public:
// Overriding virtual functions with implementations in cpp file.
void advance() override;
// The problematic function
void advance(const uint32_t N) override;
private:
uint32_t index;
};
The cpp file:
#include "Derived.h"
Derived::advance()
{
++index;
}
Derived::advance(const uint32_t N)
{
index += N;
}
Now inspecting the code for any "funny" characters like Greek question marks did not yield any result. I tried replacing the text, typing it again etc to no result
Commenting out the functions advance(const uint32_t N) resolves the problem so it is not something else in the file.
What could cause this problem?
The problem was indeed as #Clifford mentioned. N was already defined somewhere in the MSP430 code. Renaming Derived::advance(const uint32_t N) to Derived::advance(const uint32_t N_bytes) solves the problem.

Error LNK 2019 on Qt while linking a function from another file [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 3 years ago.
I am working at a university project with Qt version 4.7.2(I am using an old version because our teacher will use this version to review the project) on a Windows x86 machine but I have some problems while linking some function from the class Container to the class QListModelAdapter.
I've already tried running qmake again, clean and rebuild the project and deleting the build folder for building it from scratch but nothing of this worked, also checked my .pro file but seems like nothing wrong there.
qlistmodeladapter.h
#ifndef QLISTMODELADAPTER_H
#define QLISTMODELADAPTER_H
#include <QAbstractListModel>
#include "container.h"
class AddLayout;
class QListModelAdapter : public QAbstractListModel {
private:
Container<articolo>* model;
const AddLayout* insert;
public:
QListModelAdapter(QObject* = nullptr, const AddLayout* = nullptr);
~QListModelAdapter() override;
bool insertRows(int, int = 1, const QModelIndex& = QModelIndex()) override;
bool removeRows(int, int = 1, const QModelIndex& = QModelIndex()) override;
};
#endif
qlistmodeladapter.cpp
#include "qlistmodeladapter.h"
#include "container.h"
#include "addlayout.h"
#include <QFont>
QListModelAdapter::QListModelAdapter(QObject* parent, const AddLayout* ins) :
QAbstractListModel(parent),
model(new Container<articolo>()), insert(ins) {}
bool QListModelAdapter::removeRows(int begin, int count, const QModelIndex& parent) {
beginRemoveRows(parent, begin, begin + count - 1);
model->removeEl(begin);
endRemoveRows();
return true;
}
bool QListModelAdapter::insertRows(int begin, int count, const QModelIndex& parent) {
beginInsertRows(parent, begin, begin + count - 1);
articolo art = articolo(new Computer(insert->getNome()));
model->insertEl(art);
endInsertRows();
return true;
}
container.cpp
#include "container.h"
template<class T>
void Container<T>::insertEl(T& p)
{
if (maxSize == size)
{
increaseSize();
}
iteratore it = end();
*(it) = p;
size++;
}
template<class T>
void Container<T>::removeEl(int j)
{
if (j <= size)
{
iteratore it = begin();
for(int i = 0; i <= (j-1); i++)
{
it++;
}
delete it.punt;
iteratore aux = it;
it++;
for(int i = j; i < size-2; i++)
{
aux = it;
aux++;
it++;
}
size--;
}
}
container.h
#ifndef CONTAINER_H
#define CONTAINER_H
#include "items.h"
template<class T>
class Container
{
friend class iteratore;
private:
T* vector;
int size;
int maxSize;
public:
class iteratore {
// is defined correctly
};
Container(T* p = nullptr, int s = 0);//it is defined but not included
void removeEl(int);
void insertEl(T&);
};
#endif // CONTAINER_H
The incriminated function is removeEl and is where is get this error:
qlistmodeladapter.obj:-1: error: LNK2019: riferimento al simbolo esterno "public: void __cdecl Container<class articolo>::removeEl(int)" (?removeEl#?$Container#Varticolo####QEAAXH#Z) non risolto nella funzione "public: virtual bool __cdecl QListModelAdapter::removeRows(int,int,class QModelIndex const &)" (?removeRows#QListModelAdapter##UEAA_NHHAEBVQModelIndex###Z)
sorry but the language is set on Italian, the strange thing is that it works properly with insertEl so i don't know what to think.
I've already checked the .pro file so I'm not including it right now because there is a lot of code already.
Every help will be really appreciated, thank you a lot.
Templates are not classes. Only when a template parameter is given to them, they will be seen as implementation. That being said, in your cpp file, the methods are just method templates, they are no method implementations (yet).
Now, when you try to call the method from a different translation unit (cpp file), the linker will try to find the symbol of the method implementation but cannot find it because the compiler will not have created the corresponding symbol in the cpp file because it was never called there with the corresponding template parameter.
The solution is quite easy: whoever uses your template, needs to have the method template available, too, so that a call to a method template will urge the compiler to create this needed implementation -> move the method implementations to your header file. You can delete your cpp file for this class template altogether.
Edit: by the way, you create memory leaks here because you call new on your container class but never delete. You have two clean possibilities here: Since you use Qt, you can use the memory management of it by letting Container inherit QObject. Then, in the constructor initialize QObject with the parent that you pass to it by your list view.
An alternative way is to use unique_ptr around your container instance in QListModelAdapter. New will still work and you can access the object via pointer. But it will be cleaned up automatically.
Of course, you could also just put the Container on the stack without pointer (just removing * and accessing the object with .).
Note that manually calling delete in your own destructor is not modern C++. It makes things more complicated and you would also need to implement copy constructor and copy assignment operator. This is not necessary or recommendable in year 2019 anymore. C++ is a fresh language that has multiple ways of preventing memory leaks when used idiomatically now.
And what I also see here (this starts to become a code review) is your naming. Q as prefix for macros, function names, class names and so on should just be used by Qt. If someone uses your code, they will be confused by your naming otherwise. For such user, it could well be that your class name is an actual Qt class that they have not heart of before.

C++ - Errors when trying to insert class into map

I have a map like so map<string, unique_ptr<Base>> variables and I am trying to insert data into the map variables.insert(make_pair("foo", new Int(10))) but I am getting to following errors:
error: no matching function for call to ‘std::map<std::__cxx11::basic_string<char>, std::unique_ptr<Base>>::insert(std::pair<const char*, Int*>)’
variables.insert(make_pair("test", new Int(10)));
error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
template<typename _Pair, typename = typename
This is my code:
class Base {
public:
Base() {};
virtual ~Base() {};
};
class Int : public Base {
public:
Int(int i) {
this->i = i;
}
Int operator=(int i) {
this->i = i;
}
int i;
};
void set() {
map<string, unique_ptr<Base>> variables;
variables.insert(make_pair("test", new Int(10)));
}
I think I need a fresh pair of eyes to look at this I'm not sure what this issue is, thanks!
Edit
I'm trying to make a heterogeneous map and there's a class for each data type. But I still get the same error no matter how many there are.
Note: This answer only applies to older versions of the main three compilers:
GCC: Applies to 5.3.1 or earlier. May apply to any version earlier than 6.1.0, but I haven't tested this.
Clang: Applies to 3.7.1 or earlier. May apply to any version earlier than 3.8.0, but I haven't tested this.
Visual Studio: Applies to 19.00.23506.0 or earlier. May apply to any version earlier than 19.00.23720.0, but I haven't tested this.
Conversely, if you have GCC 6.1.0 or later, Clang 3.8.0 or later, or Visual Studio 19.00.23720.0 or later, the original code should compile as is, without either of the modifications suggested in this answer.
[Thanks goes to AndyG for pointing out that it works with later versions of GCC & Clang.]
The problem appears to be that it isn't creating your unique_ptr from your raw pointer.
If you can use C++14, try std::make_unique().
void set() {
map<string, unique_ptr<Base>> variables;
variables.insert(make_pair("test", make_unique<Int>(10)));
}
If you can't, then try something like this:
void set() {
map<string, unique_ptr<Base>> variables;
variables.insert(make_pair("test", unique_ptr<Int>(new Int(10))));
}
Interestingly, I noticed a slight difference in how different compilers handle this. Using the following slightly modified version of your code as a test program:
#include <map>
#include <memory>
#include <iostream>
class Base {
public:
Base() {};
virtual ~Base() {};
};
class Int : public Base {
public:
Int(int i) {
this->i = i;
}
Int& operator=(int i) {
this->i = i;
// You forgot to return something.
return *this;
}
int i;
};
void set() {
using namespace std;
map<string, unique_ptr<Base>> variables;
variables.insert(make_pair("test", new Int(10)));
// C++14:
// variables.insert(make_pair("test", make_unique<Int>(10)));
// C++11:
// variables.insert(make_pair("test", unique_ptr<Int>(new Int(10))));
// Cheap hack for testing.
cout << static_cast<Int*>(variables["test"].get())->i << endl;
}
int main() {
set();
}
Most compilers* will fail to compile this, unless the initial line is commented out and either of the fixes is uncommented. However, the online MSVC compiler seemed to be able to compile it fine, without needing to uncomment either of the lines. Curiously, the version of MSVC available on Rextester failed to compile it without uncommenting one of the two lines.
* Tested online, with TutorialsPoint GCC, MSVC 2015 online, and Rextester Clang, GCC, and MSVC.

g++ 4.2: internal compiler error: in make_thunk, at cp/method.c:129

I asked this question already on http://www.cplusplus.com/forum/general/96128/ but to no avail.
does anybody experienced the same bug with g++ 4.2: internal compiler error: in make_thunk, at cp/method.c:129
I think it is not neccessary to include sample code. The respective code compiles without warnings and errors on several other newer g++ versions, as well as on clang++. It is simply correct and the bug was mentioned in the GCC's bugzilla (even several times, because it seems to recurr often), but no workaround was provided.
Please don't tell also to use a newer g++. I MUST compile it on the g++ shipped with Ubuntu Hardy, so I cannot change the compiler. Main development is done on Ubuntu Precise, but I need to keep it compatible to Hardy.
I have no idea what a thunk should be, I only suspect it has to do with covariants and/or multiple inheritance. Also I have several more similar structured header files, which all compile well, despite the only change is the name is the name of the class and I have no aim, to change that because of a compiler bug on Hardy.
Another fact is, it happens at include time.
In file included from /home/heiko/hgl/src/compiler/compilerprojectfactory.cpp:18:
/home/heiko/hgl/src/compiler/compilertype.h: In instantiation of 'HGL::Compiler::CompilerType<HGL::Vector2D, HGL::Compiler::CompilerBase>':
/home/heiko/hgl/src/compiler/compilervector2d.h:23: instantiated from here
/home/heiko/hgl/src/compiler/compilertype.h:22: internal compiler error: in make_thunk, at cp/method.c:129
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
For Debian GNU/Linux specific bug reporting instructions,
see <URL:file:///usr/share/doc/gcc-4.2/README.Bug
EDIT: Here the header which causes the bug:
#include "compilertype.h"
#include "vector2d.h"
namespace HGL {
class Vector2D;
namespace Compiler {
/**
#author Heiko Schäfer <heiko#rangun.de>
*/
class _LOCAL Vector2D : public Compiler::CompilerType<HGL::Vector2D> {
DISALLOW_COPY_AND_ASSIGN(Vector2D)
public:
Vector2D(float x, float y, int line);
using IType::operator=;
virtual operator HGL::Vector2D &() const throw(InvalidExpressionException);
protected:
virtual ~Vector2D();
void append(ISerializeable::BUFFER *dest, const HGL::IType *type) const;
};
}
}
Here the template:
#include "compilerbase.h"
#include "iproject.h"
#include "util.h"
namespace HGL {
namespace Compiler {
const IProject::VSTRUCT minReq = { HGL_MINREQ_MAJOR, HGL_MINREQ_MAJOR, HGL_MINREQ_MAJOR };
template<class Type, class Base = CompilerBase>
class _LOCAL CompilerType : public Type, public Base {
DISALLOW_COPY_AND_ASSIGN(CompilerType)
public:
using IType::operator=;
template<class Param>
inline CompilerType(const Param &p, bool b, int line,
const IProject::VSTRUCT &vs = IProject::VSTRUCT()) :
Type(p), Base(line, b) {
init(vs);
}
template<class Param>
inline CompilerType(const Param &p, int line,
const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(p), Base(line) {
init(vs);
}
inline CompilerType(bool b, int line, const IProject::VSTRUCT &vs = IProject::VSTRUCT())
: Type(), Base(line, b) {
init(vs);
}
template<class Param1, class Param2>
inline CompilerType(const Param1 &p1, const Param2 &p2, int line,
const IProject::VSTRUCT &vs = IProject::VSTRUCT()) :
Type(p1, p2), Base(line) {
init(vs);
}
template<class Param1, class Param2>
inline CompilerType(const Param1 &p1, const Param2 &p2, bool b, int line,
const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(p1, p2),
Base(line, b) {
init(vs);
}
inline CompilerType(int line,
const IProject::VSTRUCT &vs = IProject::VSTRUCT()) : Type(), Base(line) {
init(vs);
}
inline virtual void append(ISerializeable::BUFFER *dest, const IType *type) const {
Base::append(dest, type);
}
protected:
inline virtual ~CompilerType() {}
inline virtual void init(const IProject::VSTRUCT &vs) {
const_cast<IProject::VSTRUCT &>(vs) = std::max(vs, minReq);
CompilerBase::setMinRequiredVersion(vs, Type::getSerialID());
}
};
}
}
RESOLVED!
After digging in g++ 4.2's source code I found out that it needs to now about all types in the complete tree. g++ > 4.2 apparently doesn't need this.
So, the error was in a related class which had a template member with a forwarded specialization. I just included the header instead of forwarding and g++ 4.2 was happy.
Otherwise it is really a non-nice bug not to give an error, but this useless message.
A thunk or trampoline is a piece of code that is added in some implementations of dynamic dispatch to adapt the interface of the base virtual function with respect to the final overrider being used. As you mentioned it is commonly needed to adapt the this pointer in multiple/virtual inheritance (for bases listed after the first non-empty one) and to adapt the resulting pointer/reference with covariant return types.
The error indicates that it is a compiler bug. If you have to use that particular compiler you will need to work around the issue, and that will involve changing your design. You can try to limit the use of multiple/virtual inheritance, reorder the bases in the list or try to play around until you manage to get the compiler to digest that code somehow. If it is a problem when generating the adapter for a covariant return type, consider removing the covariant return and provide an overload (with a different name) that will return the covariant type (i.e. replace covariant return with a non-virtual function returning the most derived type and a virtual function that calls the previous and returns a reference to the base).
Other than those generic hints, without seeing the code you have and the implementation of the compiler there is little else to say.

using template declared in other file in c++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can templates only be implemented in the header file?
What is an undefined reference/unresolved external symbol error and how do I fix it?
I have defined a template class in a file.
point.h is
#ifndef POINT_H
#define POINT_H
using namespace std;
template <typename T, int size>
class point {
private:
T coordinates[size];
public:
point();
void set_coordinates(const T *);
void get_coordinates(T *);
};
#endif /* POINT_H */
point.c is
#include "point.h"
template <typename T, int size>
point::point() {
for (int i = 0; i < size; i++)
coordinates[i] = 0;
}
template <typename T, int size>
void point<T, size>::set_coordinates(const T *coordinates) {
for (int i = 0; i < size; i++)
this->coordinates[i] = coordinates[i];
}
template <typename T, int size>
void point<T, size>::get_coordinates(T *coordinates) {
for (int i = 0; i < size; i++)
coordinates[i] = this->coordinates[i];
}
I am using this template as point<int, 2> p0;. But compiler gives error that point<int, 2> is not defined.
I searched on this and found two solutions -
1. to use export variable. But I read that it is not supported by all compilers. So, I don't want to use that.
2. to create explicit class specializations like
template <> class point<int> {
...
}
But isn't there any other way to do this? (I mean in C++ standard containers, they might have used some technique to do this.)
Read this and the next two FAQ questions - C++ FAQ
The solution of the c++ standard containers is keep everything in the header file.
You should put all the definitions belonging to the template point (that is, including the member functions) to the point.h file and include it in any file that uses the point class, so that the compiler can instantiate it as needed. See this question for details.
The C++ compilers and linkers have means to avoid "multiple definitions" error on link (the ODR rule in the standard states this must be the case).