How to declare a reference to a member in the same class? - c++

I looked at a lot of other questions and answers and no one seems to have the same question I do.
I am trying to make references to variables, both within a class. I took out the part of the larger program I am writing and isolated it in a little file: test.cpp. I thought maybe my problem had something to do with how I was using the variable with the reference, but the same messages appeared as in the larger program.
Here is my code:
#include <iostream>
class Test {
public:
int test;
int& rtest = test;
};
int main() {
std::cout << "Enter an integer: ";
std::cin >> Test.rtest;
std::cout << "\n" << Test.rtest << "\n";
return 0;
}
I received these messages:
warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11
int& rtest = test;
In function ‘int main()’: error: expected primary-expression before ‘.’ token
std::cin >> Test.rtest;
error: expected primary-expression before ‘.’ token std::cout << "\n" << Test.rtest << "\n";
Why am I getting these? Is what I am trying to do possible? If so, how can I do it?

warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 int& rtest = test;
You need to pass the flag -std=c++11 to your compiler, otherwise it defaults to an older version of C++ which doesn't allow you to initialize class members in that way.
In function ‘int main()’: error: expected primary-expression before ‘.’ token std::cin >> Test.rtest;
error: expected primary-expression before ‘.’ token std::cout << "\n" << Test.rtest << "\n";
This is because the . operator wants an instance of your class, not the class itself (that's what :: would be for). Declare e.g. Test test; and use test.rtest instead.

You need to have an instance of Test to access non static members of a class:
int main() {
Test t; // <<<<<<<<
std::cout << "Enter an integer: ";
std::cin >> t.rtest;
std::cout << "\n" << t.rtest << "\n";
}
Also you need to initialize the reference with an appropriate constructor, unless you have the -std=c++11 compiler flag enabled as the error message says:
class Test {
public:
int test;
int& rtest; // Nope! = test;
Test() : test(), rtest(test) {} // <<<<<<<<<<<<<<<<<<
};

Related

C++ error: expected unqualified-id before '[' token when using structured bindings

Preamble:
I know that there are quite some topics with the same or a similar title. Keep reading and you will understand my case.
New to C++ I'm currently reading a book that quite obviously has a corrupt example excercise.
My code
#include <iostream>
using namespace std;
struct Point {
int x;
int y;
};
int main(int argc, char const* argv[]) {
Point p1{100, 200};
auto [a, b] = p1;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
auto& [c, d] = p1;
c += 50;
d += 50;
cout << "p1.x = " << p1.x << endl;
cout << "p1.y = " << p1.y << endl;
return 0;
}
is almost an exact copy of the book. I only splitted the original one line cout into two lines and used namespace std instead of std::. Other than that the code is exactly like the example in the book.
Just to be 100% sure I'm not just having a typo, I donwloaded the example file from the books website.
We both get the same errors:
structuredBinding.cpp: In function ‘int main(int, const char**)’:
structuredBinding.cpp:14:7: error: expected unqualified-id before ‘[’ token
auto [a, b] = p1;
^
structuredBinding.cpp:16:20: error: ‘a’ was not declared in this scope
cout << "a = " << a << endl;
^
structuredBinding.cpp:17:20: error: ‘b’ was not declared in this scope
cout << "b = " << b << endl;
^
structuredBinding.cpp:19:8: error: expected unqualified-id before ‘[’ token
auto& [c, d] = p1;
^
structuredBinding.cpp:19:8: error: expected initializer before ‘[’ token
structuredBinding.cpp:21:2: error: ‘c’ was not declared in this scope
c += 50;
^
structuredBinding.cpp:22:2: error: ‘d’ was not declared in this scope
d += 50;
^
The book assumes its example exercise to work, but it doesn't.
I found some other topics regarding this or similar errors but none of them seem to work for me.
I also looked up the errata but there is no error registered for that part of the book.
I'm on Linux (Xubuntu) and I compile with g++ -std=c++17 -o <outputname> <inputname.cpp>
Can someone tell me what is wrong here? I would then report that error to the author.
To take advantage of C++17 features in GCC, you need to pass -std=c++17 on the compiler command line (e.g. by setting CXXFLAGS in your Makefile).
However, not all versions of GCC support all of the C++17 standard.
According to C++ Standards Support in GCC, you need at least g++ 7 to take advantage of structured bindings, and g++ 8 to take advantage of structured bindings to accessible members (e.g. private members from friend functions, rather than only public members).
Ubuntu 16.04 has g++ 5.4, Ubuntu 18.04 has g++ 7.3. To install a newer version of g++ on Ubuntu, see Install gcc-8 only on Ubuntu 18.04? (which applies to Ubuntu 16.04 as well) on Ask Ubuntu, particularly this answer.
I just installed gcc-8 and g++-8 packages on my Ubuntu 16.04 system, and structured bindings are now working fine.

Imitating fortran print and write syntaxes in C++

I am trying to implement a class in C++ to imitate the syntax of the print and write statements from FORTRAN.
In order to achieve this, I implemented a class fooprint and overloaded fooprint::operator, (comma operator). Since this class should print to the standard output or to a file, I also defined two macros: print (for stdout) and write (to operate on files).
I get compilation errors when trying to use write(data) a; (see below for error log). How can I get a working write statement with the above properties?
This is the code (Live Demo):
#include <iostream>
#include <fstream>
class fooprint
{
private:
std::ostream *os;
public:
fooprint(std::ostream &out = std::cout) : os(&out) {}
~fooprint() { *os << std::endl;}
template<class T>
fooprint &operator, (const T output)
{
*os << output << ' ';
return *this;
}
};
#define print fooprint(), // last comma calls `fooprint::operator,`
#define write(out) fooprint(out),
int main()
{
double a = 2.0;
print "Hello", "World!"; // OK
print "value of a =", a; // OK
print a; // OK
std::ofstream data("tmp.txt");
write(data) "writing to tmp"; // compiles with icpc; it doesn't with g++
write(data) a; // this won't compile
data.close();
return 0;
}
And the compilation message:
g++ -Wall -std=c++11 -o print print.cc
error: conflicting declaration ‘fooprint data’
#define write(out) fooprint(out),
^
note: in expansion of macro ‘write’
write(data) a;
^
error: ‘data’ has a previous declaration as ‘std::ofstream data’
error: conflicting declaration ‘fooprint a’
write(data) a;
^
error: ‘a’ has a previous declaration as ‘double a’
icpc -Wall -std=c++11 -o print print.cc
error: "data" has already been declared in the current scope
write(data) a;
error: "a" has already been declared in the current scope
write(data) a;
fooprint(out) is not the creation of a temporary but rather the declaration of a variable of type fooprint with the name provided as the argument to the macro. In order to not make this a declaration, and instead an expression, two quick changes you can make are surrounding it in parenthesis (fooprint(out)) or using brace-initialization (C++11) (fooprint{out}).

Expression list treated as compound expression

I'm trying to compile a program I got from the net. Trying to use in codeblocks but its showing errors. I don't understand what is going wrong. I've looked up in various forums but not much light is shed. Can anyone help soon? Thanks in advance
#include <functional>
#include <iostream>
int print_num(int i, int j) { return i + j; }
int main() {
std::function<int(int, int)> foo = print_num;
std::function<int(int, int)> bar;
try {
std::cout << foo(10, 20) << '\n';
std::cout << bar(10, 20) << '\n';
} catch (std::bad_function_call& e) {
std::cout << "ERROR: Bad function call\n";
}
return 0;
}
These are some of the errors other than 14 other errors saying declaration not done. I guess clearing these error would solve that problem.
main.cpp|10|error: 'function' is not a member of 'std'
main.cpp|10|error: expression list treated as compound expression in functional cast [-fpermissive]
main.cpp|10|error: expected primary-expression before 'int'
You need to compile with -std=c++11 to add in the C++11 features.
$ g++ -std=c++11 test.cxx && ./a.out
30
ERROR: Bad function call
vs:
$ g++ test.cxx && ./a.out
test.cxx: In function ‘int main()’:
test.cxx:10:3: error: ‘function’ is not a member of ‘std’
test.cxx:10:28: error: expression list treated as compound expression in functional cast [-fpermissive]
test.cxx:10:17: error: expected primary-expression before ‘int’
...

C++: cin, cout, etc. "does not name a type"

having a problem with the following piece of code:
#include <iostream>
using namespace std;
class Calculator
{
public:
int Sum(int first, int second);
};
int Calculator::Sum(int first, int second)
{
int sum = first + second;
return sum;
}
class Printer{
public:
void Print();
int first, second, calculated_sum;
cout << "Give a first integer: ";
cin >> first;
cout << "Give a second integer: ";
cin >> second;
Calculator calc;
calc.Sum(first, second);
};
void Printer::Print(){
cout << "Sum: " << sum << endl;
}
int main()
{
Printer object;
object.Print();
}
I can only touch Printer class, as the others are not created by me.
The errors I get when I try to compile this:
code.cpp:22: error: ISO C++ forbids declaration of 'cout' with no type
code.cpp:22: error: expected ';' before '<<' token
code.cpp:23: error: ISO C++ forbids declaration of 'cin' with no type
code.cpp:23: error: expected ';' before '>>' token
code.cpp:24: error: ISO C++ forbids declaration of 'cout' with no type
code.cpp:24: error: expected ';' before '<<' token
code.cpp:25: error: ISO C++ forbids declaration of 'cin' with no type
code.cpp:25: error: expected ';' before '>>' token
code.cpp:28: error: ISO C++ forbids declaration of 'calc' with no type
code.cpp:28: error: expected ';' before '.' token
code.cpp: In member function 'void Printer::Print()':
code.cpp:32: error: 'sum' was not declared in this scope
So lot's of errors for so few lines of code. Any ideas on what to try to fix this?
Basically what people are saying in the comments. You need to move
cout << "Give a first integer: ";
cin >> first;
cout << "Give a second integer: ";
cin >> second;
from sitting inside your class into some function. The area inside a class declaration is for declaring member variables and methods.
Same goes for the lines
Calculator calc;
calc.Sum(first, second);
The print method of the Printer object, for example, seems like a good place to put these lines.
Then you just need to make sure you declare sum in the scope of the print method and you should be good to go.

Preprocessor ## pasting operator

What I am trying to achieve is creation of these three classes as mentioned in the code but just trying to use pre-processer in handy so that these similar classes can be created and executed rather than writing individual codes for them:
#include <iostream>
#define MYMACRO(len,baselen)
using namespace std;
class myclass ## len
{
int MYVALUE ## baselen;
public:
myclass ## len ## ()
{
cout << endl;
cout << " For class" ## len ## "'s function 'myFunction" ## len ## "' the value is: " << MYVALUE ## baselen << endl;
}
};
int main()
{
MYMACRO(10,100)
//myclass10 ob1;
MYMACRO(20,200)
//myclass20 ob2;
MYMACRO(30,300)
//myclass30 ob3;
myclass10 ob1;
myclass20 ob2;
myclass30 ob3;
cout << endl;
return 0;
}
Now I don't know whether the it can be done & since I am getting this error. If yes then please someone solve the error and enlighten me if no then please give the reason for the same so I am also reassured that we are on same page! The error is:
[root#localhost C++PractiseCode]# g++ -o structAndPreprocessor structAndPreprocessor.cpp
structAndPreprocessor.cpp:5: error: invalid token
structAndPreprocessor.cpp:6: error: invalid function declaration
structAndPreprocessor.cpp:7: error: invalid token
structAndPreprocessor.cpp:9: error: invalid token
structAndPreprocessor.cpp:9: error: invalid token
structAndPreprocessor.cpp:12: error: invalid token
structAndPreprocessor.cpp:12: error: invalid token
structAndPreprocessor.cpp:12: error: invalid token
structAndPreprocessor.cpp:12: error: invalid token
structAndPreprocessor.cpp:12: error: invalid token
structAndPreprocessor.cpp: In function `int main()':
structAndPreprocessor.cpp:25: error: `myclass10' was not declared in this scope
structAndPreprocessor.cpp:25: error: expected `;' before "ob1"
structAndPreprocessor.cpp:26: error: `myclass20' was not declared in this scope
structAndPreprocessor.cpp:26: error: expected `;' before "ob2"
structAndPreprocessor.cpp:27: error: `myclass30' was not declared in this scope
structAndPreprocessor.cpp:27: error: expected `;' before "ob3"
[root#localhost C++PractiseCode]#
You need to use \ at each end of your line to define your macro (and likely remove the using statement from the macro)
using namespace std;
#define MYMACRO(len,baselen) \
class myclass ## len \
{ \
int MYVALUE ## baselen; \
(...snip...) \
}\
};
Note the absence of escape on last line
Most likely you're doing Cpp and using Macros is discouraged. You'd better use either templates or traditional dynamic code (dpeending on your needs). Compared to macros, template bring the additional type checking at compilation and provide much more readable error messages.
The macro solution you present is a solution I've used before, but I would look at approaching this differently. The macro solution is a unwieldy and difficult to maintain and debug for all but the most trivial code.
Have you thought about generating the code you need from a template? Using Cheetah or Mako to fill out a source template would be quite a bit cleaner, and you could drive the generation from a configuration file, so you don't have to hand-maintain your list of classes.
You'd have a myclass.tmpl template file that looks something like this :
#for len, baselen in enumerate(mylist_of_classes_i_want_to_generate)
class MyClass$len
{
int MYVALUE$baselen;
public:
MyClass$len()
{
cout << endl;
cout << " For class $len's function 'myFunction $len' the value is: " << MYVALUE$baselen << endl;
}
};
#end for
You'd then call cheetah to autogenerate the code at the start of your build flow prior to compilation.