Constructing a class in a template class - c++

I am studying about templates and typename keyword I am getting error in the following code:
/*1)*/ #include<iostream>
/*2)*/ #include<cstdio>
/*3)*/ #include<stdlib.h>
/*4)*/
/*5)*/ using namespace std;
/*6)*/
/*7)*/ class out
/*8)*/ {
/*9)*/ public:
/*10)*/ int i;
/*11)*/ out(int i,int j):i{i},ob{j}{}
/*12)*/ class in
/*13)*/ {
/*14)*/ public:
/*15)*/ int j;
/*16)*/ in(int j):j{j}{}
/*17)*/ }ob;
/*18)*/ };
/*19)*/
/*20)*/ template<typename type>
/*21)*/ class temp
/*22)*/ {
/*23)*/ public:
/*24)*/ typename type::in ob(3);
/*25)*/ type ob1(4,4);
/*26)*/ };
/*27)*/
/*28)*/ int main()
/*29)*/ {
/*30)*/ out ob(1,1);
/*31)*/ out::in ob1(2);
/*32)*/ temp<out> t;
/*33)*/ cout<<ob.i<<" "<<ob.ob.j<<endl;
/*34)*/ cout<<ob1.j<<endl;
/*35)*/ cout<<t.ob.j<<endl;
/*36)*/ cout<<t.ob1.i<<" "<<t.ob1.ob.j;
/*37)*/ }
The code shows the following error
Line Error
|24| error: expected identifier before numeric constant
|24| error: expected ',' or '...' before numeric constant
|25| error: expected identifier before numeric constant
|25| error: expected ',' or '...' before numeric constant
In function 'int main()':
|35| error: 't.temp<type>::ob<out>' does not have class type
|36| error: 't.temp<type>::ob1<out>' does not have class type
|36| error: 't.temp<type>::ob1<out>' does not have class type
=== Build failed: 7 error(s), 0 warning(s) (0 minute(s), 4 second(s)) ===
If i change the two lines
typename type::in ob(3);
type ob1(4,4);
To
typename type::in ob=typename type::in(3);
type ob1=type(4,4);
It will works fine and producing following output:
1 1
2
3
4 4
Process returned 0 (0x0) execution time : 0.847 s
Press any key to continue.
But i want to know why the error shows, How can i solve the error in above code Please help me?
Thanks for helping.

If you want to initialize variables in the definition of a class you have to use assignement syntax or curly braces. Plain paranthesis is not allowed.
typename type::in ob=typename type::in(3);
type ob1=type(4,4);
typename type::in ob{3};
type ob1{4,4};
This is unrelated to templates and works the same for all classes. One of the reasons is to make parsing easier for the compiler. As mentioned in the comments most vexing parse is an example when disambiguating between an initialization and a function declaration can be done by using {} instead of ().

Related

Boost cpp_dec_float with precision determined at run-time

Normally to create an arbitrary-length data type using Boost's cpp_dec_float, you use:
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<100> > arbFloat;
This is great and all, but it appears that the value for the precision (above it is 100) needs to be constant and determined at compile-time. For example, this code does not compile:
#include <boost/multiprecision/cpp_dec_float.hpp>
int main() {
int custom_precision = 100;
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<custom_precision> > arbFloat;
return 0;
}
and returns the following errors:
In function ‘int main()’:
5:77: error: ‘custom_precision’ cannot appear in a constant-expression
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<custom_precision> > arbFloat;
^
5:93: error: template argument 1 is invalid
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<custom_precision> > arbFloat;
^
5:95: error: template argument 1 is invalid
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<custom_precision> > arbFloat;
^
5:95: error: template argument 2 is invalid
But when int custom_precision is instead constant: const int custom_precision the program compiles fine.
Is there a way to use Boost's cpp_dec_float with the precision determined at run-time, or some way to at least trick it?
I plan to use it with command line parsing, so that I can do something like:
$ ./test_program --precision 500

Error while compiling in gcc

I am doing a project for my class where the instructor had given us some code snippets and we were asked to modify it. The code compiles correctly in my class computer in Visual Studio but when I try to compile it with gcc it gives me an error.
The error I am getting is:
||=== Build: Debug in Project (compiler: GNU GCC Compiler) ===|
/home/nitin/Read.h|45|error: declaration of ‘std::vector<rv> rvs::rv’ [-fpermissive]|
/home/nitin/Read.h|35|error: changes meaning of ‘rv’ from ‘struct rv’ [-fpermissive]|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
The code from the error is snippet for this is:
struct rv
{
double val, prob;
rv(const double v, const double p): val(v), prob(p) {};
};
struct rvs
{
int row_n, col_n;
vector<rv> rv;
rvs(const int r=-2, const int c=-2): row_n(r), col_n(c) {};
};
Could you please let me know what the problem could be?
Your declarations violate the following rule
3.3.7 Class scope [basic.scope.class]
1 The following rules describe the scope of names declared in classes.
...
2) A name N used in a
class S shall refer to the same declaration in its context and when
re-evaluated in the completed scope of S. No diagnostic is required
for a violation of this rule.
At the point of vector declaration name rv refers to a type struct rv. But when reevaluated in the scope of complete class rvs it, refers to class member rvs::rv. Such inconsistency is an error in C++.
A similar error is illustrated by an example in the standard
enum { i = 1 };
class X {
char v[i]; // error: i refers to ::i
// but when reevaluated is X::i
...
enum { i = 2 };
};
As #Ben Voigt stated in the comment, if you explicitly resolve the conflict between rv as struct rv and rv as rvs::rv, the error will go away. You can do it by either using elaborate type specifier struct rv or by specifying scope explicitly ::rv.
Note that this is one of those errors which are not guaranteed/required to be caught by the compiler.
You have a type called rv and a member variable called rv. How is the compiler supposed to know which one you mean when you write rv?
Strictly this is invalid code, but Visual Studio seems to be willing to try to let you shoot yourself in the foot.

Code Blocks C++ Error expected primary expression before enum

I am self teaching myself in C++ so I just would like to ask for your forgiveness if my question is really basic.
I am following a tutorial on www.learncpp.com
According to the tutorial, I could define my c++ array such as like this
int main()
{
using namespace std;
enum ArrayElements
{
MAX_ARRAY_SIZE = 5;
};
int anArray[MAX_ARRAY_SIZE];
return 0;
}
But codeblock keep on issuing error
||=== Build: Debug in CH6 (compiler: GNU GCC Compiler) ===|
In function 'int main()':|
|6|error: expected primary-expression before 'enum'|
error: expected ';' before 'enum'|
||=== Build failed: 2 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|
I just dont know what is causing the error or is there a problem with the tutorial I am following?
Remove the semicolon inside the enum.
MAX_ARRAY_SIZE = 5;
// ^
If you do have more names inside the enum, separate them with a comma ,
enum COLOR
{
RED,
BLUE,
GREEN
};
replace enum ArrayElements block with following code
int MAX_ARRAY_SIZE = 5;

c++ weird struct and bitset error

I have this inside my private class declarations
#include "stdafx.h"
using namespace std;
template <typename Key, typename T>
class A{
//....
private:
static const unsigned int HSIZE = 32;
struct Bucket {
Key key;
T value;
bitset<HSIZE> jumpMap;
};
//....
};
Gives the following errors:
Error 1 error C4430: missing type specifier - int assumed
Error 2 error C2059: syntax error : '<'
Error 3 error C2238: unexpected token(s) preceding ';'
And when i remove the bitset line, it gives me no errors. What am i doing wrong?
EDIT: Added more relevant lines
Have you included the bitset header? I think you have missed it?
Should HMAX be HSIZE instead? Otherwise make sure you include < bitset >, and that the name is in scope. You probably have a using namespace std in your code, since you don't qualify it with std::. But my bet goes to HMAX <-> HSIZE.

namespaces ; expected unqualified id before ')' token ; invalid use of struct

I am new to c++ and am trying to understand namespaces and how they work
I thought i'd code up a simple "hello world" program using namespaces but as it turned
out, it seems to have backfired on me and i am getting a bunch of weird errors.
Here is my code:
#include <iostream>
namespace names
{
using namespace std;
void class hello() //line 7 <-- here is where the compiler is complaining
about the 'unqualified id'
{
cout <<"Hello World";
}
}
int main()
{
names::hello(); //line 16
}
And here is the output:
E:\CB_Workspace\Names\names_main.cpp|7| error: expected unqualified-id before ')' token|
E:\CB_Workspace\Names\names_main.cpp|| In function 'int main()':|
E:\CB_Workspace\Names\names_main.cpp|16| error: invalid use of incomplete type 'struct names::hello'|
E:\CB_Workspace\Names\names_main.cpp|7| error: forward declaration of 'struct names::hello'|
||=== Build finished: 3 errors, 0 warnings ===|
I am not sure what is going on and I have tried to search through other posts on this error.
The other post i found on this did not really address the context of namespaces.
g++ error - expected unqualified-id before ')' token
Any help would be much appreciated. Thank you
edit: ok thanks guys. I removed the "class" under my namespace and it works now. I'll flag it to be closed now. Thanks for the help
You are not trying to write a class there. A class is different than a function. Please try:
void hello()
This has nothing to do with namespace.
In C/C++ the rule for declaring a function is:
returnType functionName(functionArgument1,functionArgument2,...);
Your way of declaring the function does not follow the C/C++ rule. What you have is:
void class hello();
It should be:
void hello();
Probably you are confusing it with syntax to define the function outside the class body. In that case the rule is:
returnType className::functionName(functionArgument1, functionArgument2,...)
{
}
Namespace does not affect how function is declared. It defines where the function is available
void class hello()
Huh? How can a function also be a class? Just remove that:
void hello()