inherit constructors from vector - c++

In Stroustrup, C++ Programming Language 4th Edition, he wrote the on page 79 the following code:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <allocators>
using std::vector;
using namespace std;
template<class T>
class Vector : vector<T>
{
private:
T elem[50];
int size;
public:
***using vector<T>::vector; // inherit constructors***
T& operator[](size_type i) { check(i); return this−>elem(i); }
const T& operator=(size_type i) const {
check(i);
return this−>elem(i);
}
void check(size_type i) { if (this−>size()<i) throw Bad_index(i); }
};
int _tmain(int argc, _TCHAR* argv[])
{
Vector <int> V{ 1, 2, 3, 4 };
return 0;
}
When I compile the program, I receive the following errors:
Error 3 error C2440: 'initializing' : cannot convert from
'initializer-list' to 'Vector' c:\computer programming\c++
programming
language\code\ch3\consoleapplication3\consoleapplication3\consoleapplication3.cpp 28 1 ConsoleApplication3
Error 1 error C2886: 'vector>' : symbol cannot
be used in a member using-declaration c:\computer programming\c++
programming
language\code\ch3\consoleapplication3\consoleapplication3\consoleapplication3.cpp 17 1 ConsoleApplication3
Error 2 error C2886: 'vector>' : symbol cannot
be used in a member using-declaration c:\computer programming\c++
programming
language\code\ch3\consoleapplication3\consoleapplication3\consoleapplication3.cpp 17 1 ConsoleApplication3
4 IntelliSense: no instance of constructor "Vector::Vector [with
T=int]" matches the argument list
argument types are: (int, int, int, int) c:\Computer Programming\C++ Programming
Language\Code\Ch3\ConsoleApplication3\ConsoleApplication3\ConsoleApplication3.cpp 28 16 ConsoleApplication3
My question involves mostly Error 2 error C2886: which refers to the using directive. Visual Basic defines the error as follow:
'class::identifier' : symbol cannot be used in a member using-declaration
A using declaration uses a symbol, such as a namespace name. A using declaration is for declaring base class members.
Stroustrup apparently uses it but I have failed to duplicate his method. Is there a header I am missing or what? Could someone explain my error? thank you jmg.

Related

Can't deserialise from Json using nlohman json using custom class with private members

Really struggling to do this; it should be really simple, but I can't work out how. I've got it working for struct, but not for a class with private members. Following instructions from (https://github.com/nlohmann/json). I'm building this on Visual Studio 2019 and obtained the library from nuget, version 3.10.4.
The error is on the get line in main.cpp, where it says "no matching overloaded function call found.". There are two other errors listed;
Error (active) E0304 no instance of overloaded function
"nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType,
NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType,
JSONSerializer, BinaryType>::get [with ObjectType=std::map,
ArrayType=std::vector, StringType=std::string, BooleanType=bool,
NumberIntegerType=int64_t, NumberUnsignedType=uint64_t,
NumberFloatType=double, AllocatorType=std::allocator,
JSONSerializer=nlohmann::adl_serializer,
BinaryType=std::vector<uint8_t, std::allocator<uint8_t>>]" matches the
argument
list Assignment4 C:\Users\allsoppj\source\repos\Assignment4\Assignment4\main.cpp 120
object type is: json
Error C2672 'nlohmann::basic_jsonstd::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>::get':
no matching overloaded function
found Assignment4 C:\Users\allsoppj\source\repos\Assignment4\Assignment4\main.cpp 120
Error C2893 Failed to specialize function template 'unknown-type
nlohmann::basic_jsonstd::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>::get(void)
noexcept()
const' Assignment4 C:\Users\allsoppj\source\repos\Assignment4\Assignment4\main.cpp 120
Here's my address1.h
#include <nlohmann/json.hpp>
#include <string>
using json = nlohmann::json;
class address1 {
private:
std::string street;
int housenumber;
int postcode;
public:
address1(std::string street, int housenumber, int postcode);
NLOHMANN_DEFINE_TYPE_INTRUSIVE(address1, street, housenumber, postcode);
};
address1.cpp
#include "address1.h"
address1::address1(std::string street, int housenumber, int postcode) :street(street), housenumber(housenumber), postcode(postcode) {}
main.cpp
int main(int argc, const char** argv) {
address1 p1 = { "home",2,3 };
json j = p1;
auto p3 = j.get<address1>();
std::cout << std::setw(2) << j << std::endl;
}
The problem is that your address1 type does not have a default constructor. From https://nlohmann.github.io/json/features/arbitrary_types/#basic-usage :
When using get<your_type>(), your_type MUST be DefaultConstructible.
(There is a way to bypass this requirement described later.)
If I add address1() = default; to your example, then it compiles no problem.
Ps. The "bypass described later" can be found here: https://nlohmann.github.io/json/features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types

How to pass an enum class which is inside another class's function by reference?

I am still fairly new to C++, so sorry if the code is a bit amateurish, that might be the source of the problem.
I've spent some time searching this site and across the web. There are plenty of examples using enums (not enum class) and also of using enums and enums class outside of classes, but didn't really find anything useful for my particular scenario, see below. Of course, I may have seen the answer, but my C++ is not advanced enough yet to recognize it.
Basically I want to pass 2 "state" enums classes into a method, in a different class from the ones in which the enums classes are defined, and then change the state of the second enum class based on the value in the first enum class. These enum classes are defined inside a class which contains a pointer to the second class in which the method is defined. Class declarations are in header files and defined in separate .cpp files which include the relevant headers. See the detailed code and errors below.
Hoping someone can help me interpret the error messages at the end and figure out how to achieve this.
main.cpp
#include <iostream>
#include "firstfile.h"
int main() {
FirstFile firstobject;
firstobject.Function1();
}
Basically, I've got 2 enum classes inside following class.
firstfile.h
#include "secondfile.h"
class FirstFile
{
protected:
SecondFile secondobject;
public:
enum class enum1 {
Option1,
Option2
} enumIn = enum1::Option1;
enum class enum2 {
Option3,
Option4
} enumInOut = enum2::Option3;
// Methods
protected:
public:
void Function1();
};
firstfile.cpp
#include <iostream>
#include "firstfile.h"
void FirstFile::Function1()
{
std::cout << "Before the function call enumIn = Option 1 and enumInOut = Option3 " << std::endl;
secondobject.function2(enumIn, enumInOut);
if (enumInOut == enum2::Option4) {
std::cout << "After the function call enumInOut = Option 4" << std::endl;
}
else if (enumInOut == enum2::Option3) {
std::cout << "After the function call enumInOut = Option 3" << std::endl;
}
else {
std::cout << "enumInOut didn't match either Option 3 or Option 4" << std::endl;
}
}
The header file, where most of the errors occur.
secondfile.h
#include "firstfile.h"
class SecondFile
{
public:
void function2(const enum1& enumIn, enum2& enumInOut);
};
Finally, here is the method in class2 that is being called that should update enum2 based on the value of enum1.
secondfile.cpp
#include <iostream>
#include "firstfile.h"
#include "secondfile.h"
void SecondFile::function2(const enum1& enumIn, enum2& enumInOut)
{
if (enumIn == FirstFile::enum1::Option1) {
enumInOut = FirstFile::enum2::Option4;
}
}
The errors are:
firstfile.cpp
\secondfile.h(16, 28) : error C4430 : missing type specifier - int assumed.Note : C++ does not support default - int
\secondfile.h(16, 28) : error C2143 : syntax error : missing ',' before '&'
\firstfile.cpp(8, 42) : error C2660 : 'SecondFile::function2' : function does not take 2 arguments
\secondfile.h(16, 7) : message: see declaration of 'SecondFile::function2'
Main.cpp
\secondfile.h(16, 28) : error C4430 : missing type specifier - int assumed.Note : C++ does not support default - int
\secondfile.h(16, 28) : error C2143 : syntax error : missing ',' before '&'
secondfile.cpp
\secondfile.h(16, 28) : error C4430 : missing type specifier - int assumed.Note : C++ does not support default - int
\secondfile.h(16, 28) : error C2143 : syntax error : missing ',' before '&'
\secondfile.cpp(5, 39) : error C4430 : missing type specifier - int assumed.Note : C++ does not support default - int
\secondfile.cpp(5, 39) : error C2143 : syntax error : missing ',' before '&'
\secondfile.cpp(6, 6) : error C2065 : 'enumIn' : undeclared identifier
\secondfile.cpp(7, 3) : error C2065 : 'enumInOut' : undeclared identifier
Hope this all makes sense and look forward to any insights to help understand the cause of the errors and how I might be able to resolve them.
It's probably related to scope, but hoping to learn from this experience.
You have two issues:
You have circular dependencies, since you add the header of each classes to each other's header files. You can solve it via pointers members. Make the class member secondobject in the class FirstFile as a pointer, and provide a forward declaration in the header (i.e. in firstfile.h) for SecondFile.
Secondly, you need to specify the enum1 and enum2 from which class/ scope it is. You can use the using specifier for this, and enums will be available for the entire class SecondFile's scope.
That means, you need something like: (See Online)
firstfile.h
class SecondFile; // forward declaration
class FirstFile
{
protected:
SecondFile* secondobject{ nullptr }; // or smart pointers
public:
// ...enums and functions
};
firstfile.cpp
#include <iostream>
#include "secondfile.h"
void FirstFile::Function1()
{
// ...other code
if(secondobject)
secondobject->function2(enumIn, enumInOut);
// ^^^^^^^^^^^^
}
secondfile.h
#include "firstfile.h"
class SecondFile
{
public:
using enum1 = FirstFile::enum1; // specify from where the enums are
using enum2 = FirstFile::enum2;
void function2(const enum1& enumIn, enum2& enumInOut);
// ...other codes
};
secondfile.cpp
#include "secondfile.h"
void SecondFile::function2(const enum1& enumIn, enum2& enumInOut)
{
if (enumIn == enum1::Option1) {
enumInOut = enum2::Option4;
}
}

"Symbol cannot be defined within 'unrelated_namespace'" - lambda nested in lambda-passed-as-argument

The following code will compile with FIXME defined, but not without. The compiler in question is visual studio 2013.
#include <functional>
#ifdef FIXME
namespace unrelated_namespace {
struct ned {};
}
#endif
namespace something {
struct do_something {
template <typename T>
do_something(T f) {}
};
}
using namespace something;
do_something my_something([](){
std::function<void(void)> inner([]{});
});
#ifndef FIXME
namespace unrelated_namespace {
struct ned {};
}
#endif
The errors are as follows:
Error 2 error C2888: '<lambda_22ffa30be171afdd76e6bc1bf85e9dd7>::()::<lambda_cac50c1ea5c52e062ca61c564ead686c>' :
symbol cannot be defined within namespace 'unrelated_namespace'
C:\hudson\workspace\phtest_build_windows\replication_dev\kernel\foe\test\serialize_unit.cpp 20 1 foe
Error 3 error C2888: '<lambda_22ffa30be171afdd76e6bc1bf85e9dd7>::<helper_func_cdecl>::<lambda_8c92b136dc3e83c8e0db25c06e4203d5>' :
symbol cannot be defined within namespace 'unrelated_namespace'
C:\hudson\workspace\phtest_build_windows\replication_dev\kernel\foe\test\serialize_unit.cpp 20 1 foe
Error 3 error C2888: '<lambda_22ffa30be171afdd76e6bc1bf85e9dd7>::<helper_func_cdecl>::<lambda_8c92b136dc3e83c8e0db25c06e4203d5>' :
symbol cannot be defined within namespace 'unrelated_namespace'
C:\hudson\workspace\phtest_build_windows\replication_dev\kernel\foe\test\serialize_unit.cpp 20 1 foe
G++ eats the code with no complaint (e.g. http://ideone.com/ZEPYE7).
Is there an explanation for this behaviour other than a compiler bug?

Depth-first search algorithm implementation

The following C++ Depth-first search program won't compile.
#include <iostream>
using namespace std;
class Stack
{
private:
const int size=20;
int *st;
int top;
public :
Stack(){
st =new int[size];
top=-1;
}
~Stack(){
delete[] st;
top=-1;
}
void push(int j){
st[++top]=j;
}
int pop(){
return st[top--];
}
int peek(){
return st[top];
}
bool empthy(){
return (top==-1);
}
};
class Vertex{
public:
char label;
bool visited;
public:
Vertex(){
}
Vertex(char lab){
label=lab;
visited=false;
}
};
class Graph{
private:
const int maxvertex=20;
Vertex* vertexlist;
int **adj;
int nverts;
Stack *stack;
public:
Graph(){
vertexlist=new Vertex[maxvertex];
adj=new int*[maxvertex];
for (int i=0;i<20;i++)
adj[i]=new int[maxvertex];
nverts=0;
for (int i=0;i<maxvertex;i++){
for (int j=0;j<maxvertex;j++){
adj[i][j]=0;
}
}
stack=new Stack();
}
void add(char lab){
vertexlist[nverts++]=new Vertex(lab);
}1
};
int main(){
return 0;
}
Here are the compilation errors I am getting:
> 6 IntelliSense: no operator "=" matches these
> operands c:\users\datuashvili\documents\visual studio
> 2010\projects\dfs\dfs\dfs.cpp 76 23 DFS 7 IntelliSense: expected a
> declaration c:\users\datuashvili\documents\visual studio
> 2010\projects\dfs\dfs\dfs.cpp 77 3 DFS Error 1 error C2864:
> 'Stack::size' : only static const integral data members can be
> initialized within a class c:\users\datuashvili\documents\visual
> studio 2010\projects\dfs\dfs\dfs.cpp 8 1 DFS Error 3 error C2864:
> 'Graph::maxvertex' : only static const integral data members can be
> initialized within a class c:\users\datuashvili\documents\visual
> studio 2010\projects\dfs\dfs\dfs.cpp 54 1 DFS Error 2 error C2758:
> 'Stack::size' : must be initialized in constructor base/member
> initializer list c:\users\datuashvili\documents\visual studio
> 2010\projects\dfs\dfs\dfs.cpp 12 1 DFS Error 4 error C2758:
> 'Graph::maxvertex' : must be initialized in constructor base/member
> initializer list c:\users\datuashvili\documents\visual studio
> 2010\projects\dfs\dfs\dfs.cpp 60 1 DFS Error 5 error C2679: binary '='
> : no operator found which takes a right-hand operand of type 'Vertex
> *' (or there is no acceptable conversion) c:\users\datuashvili\documents\visual studio
> 2010\projects\dfs\dfs\dfs.cpp 76 1 DFS
Change
const int size=20;
to
static const int size=20;
(static means it will be initialized once per-class, not per-object which would require an initialization list)
vertexlist[nverts++]=new Vertex(lab);
Your trying to set a Vertex to a Vertex*. This won't compile.

Help with error: ISO C++ forbids declaration of 'vector' with no type

As the title states, I'm not sure why I'm getting this error. I've put together a test.cpp that's similar to this structure, and it works fine. Also, other than the vector problem, there's the other problem about 'protected', which isn't even in the code. I think 'protected' is a macro, so no telling what's there. I'm new to QT, so I'm likely "doing it wrong." That's certainly what the compiler's suggesting.
In file included from DrvCrystalfontz.cpp:8:
LCDText.h:28: error: ISO C++ forbids declaration of 'vector' with no type
LCDText.h:28: error: expected ';' before '<' token
LCDText.h:30: error: ISO C++ forbids declaration of 'vector' with no type
LCDText.h:30: error: expected ',' or '...' before '<' token
LCDText.h:46: error: expected ':' before 'protected'
LCDText.h: In constructor 'LCDText::LCDText(int, int, int, int, int, int, int, QObject*)':
LCDText.h:33: error: expected '{' at end of input
scons: *** [DrvCrystalfontz.o] Error 1
scons: building terminated because of errors.
Here's the code. I've numbered the lines noted in the error.
#ifndef __LCD_TEXT__
#define __LCD_TEXT__
#include <vector>
#include <QObject>
#include "LCDBase.h"
#include "WidgetText.h"
#include "WidgetBar.h"
#include "WidgetHistogram.h"
#include "WidgetIcon.h"
#include "WidgetBignums.h"
#include "WidgetGif.h"
class LCDText: public LCDBase, public virtual QObject {
Q_OBJECT
protected:
char *LayoutFB;
char *DisplayFB;
int GOTO_COST;
int CHARS;
int CHAR0;
int LROWS;
int LCOLS;
int DROWS;
int DCOLS;
vector<vector<char *> > chars; // Line 28
void (*TextRealWrite) (const int row, const int col, const char *data, const int len);
void (*TextRealDefchar) (const int ascii, const vector<char *> matrix); // Line 30
public:
LCDText(int rows, int cols, int xres, int yres, int _goto, int chars,
int char0, QObject *parent) : LCDBase(xres, yres), QObject(parent); // Line 33
~LCDText();
void TextInit(int rows, int cols);
void TextBlit(int row, int col, int height, int width);
void TextClear();
void TextClearChars();
void TextGreet();
void TextDraw(WidgetText widget);
void TextBarDraw(WidgetBar widget);
void TextHistogramDraw(WidgetHistogram widget);
void TextIconDraw(WidgetIcon widget);
void TextBignumsDraw(WidgetBignums widget);
void TextGifDraw(WidgetGif widget);
public signals: // Line 46
void SpecialCharChanged(int ch);
public slots:
void TextSpecialCharChanged(int ch);
};
#endif
Vector resides in the std namespace. You have to do one of the following:
Prepend the type with the namespace:
std::vector<std::vector<char *> > chars;
Tell the compiler you are using vector from the std namespace
using std::vector;
vector<vector<char *> > chars;
Or, tell the compiler you are using the std namespace, which will bring in everything (not recommended, see comments)
using namespace std;
every symbol declared in C++ standard library is part of the std namespace. In order to use these declarations you have to refer it by its full name. namely std::.
As MichaelM answered you should use std::vector instead of vector.
You can, however, use the following "using declarations":
1. using std::vector;
2. using namespace std; // using namespace ...; is mostly discouraged as it causes a mass-import of symbols into the global namespace
On any case, most of the time you should avoid using declaration in header files as it pollutes the global namespace for every user of your header.
good luck