C++|Storing user input to template variables - c++

I want somehow to remove all restrictions from input, what I mean:
int x;
cin >> x;
this allows the user to "answer" only with an integer, if the user writes a string as an input, either nothing or errors happen, if the "answer" is a float or double the number will be converted to int and data will be lost.
I want to solve that problem, I remembered templates that allow you to do functions more generic you do not need to care that much about data types, so I thought that I could use that to input and make input more generic, freer, but it does not work even if I make the function that does the input a method.
The code:
#include <iostream>
template <class T>
class C {
public:
T x;
void f(){
std::cin >> x;
}
};
int main(int argc, char *argv[])
{
C obj;
obj.f();
return 0;
}
The error:
error: use of class template 'C' requires template arguments
C obj;
^
<stdin>:4:7: note: template is declared here
class C {
If you know or you can imagine something please consider answering to my question, anything as long as it gives the results I want, the knowledge I seek its considered a solution (if possible not too long in lines of code && not too complicated)

First of all, the declaration C obj; basically makes no sense, as C is a template class. As an example, this would be like declaring std::vector vec; instead of std::vector<int> vec;. But apart from that, std::cin will not put whatever input it gets into whatever variable it gets. You would need to get the input into a string, then parse it. For this, I suggest making a separate singleton that overloads operator>>().

Related

How do I capture this struct vector? c++

So I've made a class, one of it's function returns a struct vector, like so:
vector<highscore::players> highscore::returnL(){
load();
return list;
}
So list is basically,
struct players {
string name;
int score;
};
vectors<players> list;
In my source cpp, I tried to capture this vector, so I made another struct and struct vector.
Source.cpp:
struct players1 {
string name;
int score;
};
vector<players1> highscorelist;
Then I tried to
highscore high; //class' name is highscore
highscorelist = high.returnL();
But I get the error message:
No operator "=" matches these operands
" operand types are std::vector<players1, std::allocator<players1>> = std::vector<highscore::players, std::allocator<highscore::players>> "
Is it not possible to do it this way?
I honestly don't know what to search for so this might have been answered before, apologize if that's the case.
You could use reinterpret_cast, but that's not a good solution. Why don't you use highscore::player?
std::vector<highscore::player> highscoreList;
highscoreList = high.returnL(); // ok
highscore::player and player1 are different types, even though they have the same variables and probably even the same memory layout. You cannot just interchange types like that. Also, if you change one of those types, you have to change the other, which is just a maintenance nightmare if it were possible.
If you can, you could also use auto:
auto highscoreList = high.returnL();

Passing array of objects to a class

#include "average.c++"
#include "name.c++"
class Grade {
public:
Grade() {}
void searcharray(Name *array[]) {
int i;
for(i = 0; i <= 10; i++){
printf("%s", array->name);
}
}
};
int main() {
int i;
char line[64];
Name *names[10];
for(i = 0; i < 5; i++){
scanf("%s", &line);
names[i] = new Name(line);
}
Grade *test;
test = new Grade();
test->searcharray(names);
}
This code gives the error
"grade.c++ in member function 'void Grad::searcharray(Name*)':
grade.c++:11:25: error: request for member 'name' in ' array', which is of pointer type 'Name*' (maybe you meant to use '->' ?)"
I need help making this work. I am guessing it is something simple like extending the class like you would in Java but not sure how this works in c++.
I am assuming you can pass an array of objects to a class like you would in C with just an array.
The root to my question is to find a solution and to get a reason for this code being wrong.
Your code can be substantially improved by taking advantage of the Standard library. The problem with your initial code was that you were doing array->name where array was a C-style array (technically the pointer into which it decayed). An expression like that isn't possible unless you obtain the pointer at the index first:
array[i]->name;
Moreover, the for loop in which that line was written is traversing the array 1 too many times. The conditional statement i <= 10 should be i < 10 so you won't dereference an address past the end of the array.
Anyway, instead of showing your code with the corrections, I thought I might as well show you what it should look like if you use vectors, memory-management, and std::string. I hope this helps:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class Grade
{
public:
Grade() { }
static void searcharray(const std::vector<std::unique_ptr<Name>>& array)
{
for (const auto& obj : array)
{
std::cout << obj->name;
}
}
};
int main()
{
std::string name;
std::vector<std::unique_ptr<Name>> names;
while (std::cin >> name)
names.push_back(std::unique_ptr<Name>(new Name(name)));
// names.push_back(std::make_unique<Name>(name))
Grade::searcharray(names);
}
Note that I also made searcharray static since it has nothing to do with a given instance of Grade.
As others have pointed out the problem is that you're using a parameter declared Name *array[] like array->name.
Remember that C++ built on top of C, which follows a rule 'declaration mimics use', which means that the way a variable is declared looks like the way it is used. So with the declaration:
Name *array[]
The way you get a name out of this is:
*array[i]
And name is a member of Name so you have to get a Name object first. Then you can tack on member access:
(*array[i]).name
And then you can use the -> shortcut where (*x).y is the same as x.y:
array[i]->name
Other issues:
Your code appears to be heavily influenced by the style of code required for the 1989 or 1990 version of C. You should try to avoid that as it makes writing C++ code much worse than it has to be.
You declare a Grade * and allocate it immediately. You can combine the declaration with initialization into:
Grade *test = new Grade();
But you don't need to use a pointer anyway: use Grade test; (and if you did need a pointer then you should use a smart pointer. Never use 'naked' new.)
Similarly you can avoid new when you create Names.
Name names[10]; // assuming that Name is default constructible
for(...) {
...
name[i] = Name(line);
}
You should avoid a fixed size array here. Instead you should default to using std::vector:
std::vector<Name> names;
for (...) {
...
names.push_back(Name(line)); // or in C++11 names.emplace_back(line);
}
You should declare the variable i as part of the for loop, not as a variable outside it:
for (int i=0; i<10; ++i)
When you read input you should avoid scanf and fixed sized buffers. Instead, if you're reading lines you should probably start off with std::getline and std::string.
std::string line;
while (std::getline(std::cin, line)) { // read as many lines as there are, not just 10 no matter what
names.emplace_back(line);
}

Need help understanding struct, and a few errors with program

I don't get how to use structs properly to achieve my goal of calculating Fractions (it is required). Quite frankly I don't have much of an idea of what I'm doing, this is only my 3rd class in C++ and I feel lost...this was the task assigned to us
Your enter() function accepts a fraction from the user. Your
simplify() function simplifies the fraction that it receives, if
possible. Your display() function displays the fraction that it
receives.
Your global functions use a Fraction type. A Fraction type holds the
numerator and denominator of a fraction as separate data members.
This is my program, only the main EXCEPT the "cin" and "cout" and the GCF function was provided by the professor, all other functions and struct outside of the main i tried to do myself...
#include <iostream>
using namespace std;
void entry (int a, int b);
void simplify (double c);
void display(int x, int y)
int main()
{
struct Fraction fraction;
cout << "Enter a numerator: " << endl;
cin >> fraction.num;
cout << "Enter a denominator: " << endl;
cin >> fraction.den;
cout << "Fraction Simplifier" << endl;
cout << "===================" << endl;
enter(&fraction);
simplify(&fraction);
display(fraction);
}
struct Fraction {
int num;
int den;
}
struct Fraction fraction{
fraction.num;
fraction.den;
}
void display(int num, int den) {
cout << fraction.num << endl;
cout << fraction.den << endl;
}
// Great Common Factor (Euclid's Algorithm), provided by Professor
int gcf( int num1, int num2 )
{
int remainder = num2 % num1;
if ( remainder != 0 )
{
return gcf( remainder,num1 );
}
return num1;
}
these are my errors:
w2.cpp: In function 'int main()':
w2.cpp: 14: error: aggregate 'Fraction fraction' has incomplete type and cannot be defined
w2.cpp: 23: error: 'enter' was not declared in this scope
w2.cpp: At global scope: w2.cpp:35: error: function definition does not declare parameters
w2.cpp: In function 'void display(int, int)':
w2.cpp: 41: error: 'fraction' was not declared in this scope
I'm sorry for the really long post, but any and all help is greatly appreciated.
AND if someone could point me to a helpful C++ book that I could read while at home and or in lectures (because of a language barrier i cannot understand my prof well enough) would also be appreciated
Let's walk through these:
error: aggregate 'Fraction fraction' has incomplete type and cannot be defined
Now, in main(), you said struct Fraction fraction;. At this point, you're forward-declaring your struct. It is not complete, so you can't use it as if it were.
You should have your whole Fraction struct defined before main(). Also note that the struct in struct Fraction fraction; is unnecessary, and left over from C.
error: 'enter' was not declared in this scope
Simple. You've declared entry() up top, but you're trying to use enter(). Not much more to be said.
At global scope: w2.cpp:35: error: function definition does not declare parameters
Now this is a bit more confusing. This is the offending line:
struct Fraction fraction{
How the compiler sees this is that it is a function returning a Fraction, but it's missing its parameter list. I'm not exactly sure what you're trying to do with this block of code.
error: 'fraction' was not declared in this scope
Looks like you're trying to use an object declared somewhere else. If you want the one from main(), you'll have to pass it in as an argument. If you want a global variable fraction, all you need in the global space is:
Fraction fraction;
This should occur after the Fraction struct. Also note that because this has the same object name as the one in main(), the one in main() shadows this one, and if you want to access the global one from main() you need to use ::fraction.
I hope that helps clear up some of the understanding.
Some other errors I see are:
enter(&fraction);
You're passing a Fraction * to a function that takes two ints. I think you'd want this one to take a Fraction &. Then you can just call it like enter (fraction); to have it modify the object passed in.
simplify(&fraction);
Similar, but this one takes a double. I think you'd want it to take a Fraction & as well.
Your entry and simplify functions never get defined, but you still try to use them.
display should take a Fraction in order to print the parts of it.
A list of recommended books on C++. Searching this site helps too.
In C++, structures (or classes) and unions form the two basic types of user defined data structure. A user defined data structure is a model/blue-print of something (it could be a real-world quantity or an abstract concept) you want your program to work with. So, if you wanted a structure to store your friends' names, you'd probably do something like this:
struct FriendName {
std::string first, last;
}; // the semi-colon is required here
first and last are the members of your struct. std::string is the type of these members which tells the compiler what sort of data you want to store -- the data here being strings we use the appropriate type defined by the library.
Once you've defined something called a FriendName you can use it to store data and also work with this data. However, if you try to define FriendName again, the compiler will complain. Which is what is happening with your code.
Now, in order to use this data structure, you will need to create an object (which is a region of memory that represents a particular FriendName instance). You can create an object as follows:
FriendName fred; // note that I don't need to use struct FriendName
and you can go ahead and use it as:
fred.first = "Fred"; // write 'fred' object's first name
fred.last = "Flintstone";
The object name works as a marker which when combined with with the . operator and a member name allows you to read/write that particular member.
Assume you wanted to read in the names from the console: In that case you'd do:
FriendName wilma;
std::cin >> wilma.first >> wilma.last; // read in 'wilma' objects members one by one
Now, there's enough up there to get you started!

C++. Get typename of a data as type, not as string

Before i start i will divide the problem into two parties:
PART 1 :
In c++ to get type of data we can use typeid but it's give you the data as const char* ,and i want it to return the type of the data.
Example:
int data = 20 ;
float data2 = 3.14 ;
char *data3 = "hello world" ;
std::cout<< typeid(data).nam() << endl << endl ;
std::cout<< typeid(data2).nam() << endl << endl ;
std::cout<< typeid(data3).nam() << endl << endl ;
Now i have a function that get data from void* , and convert it to another type :
template <typename t >
void print (void *data )
{
boost::any _t = static_cast<t> (data);
cout << boost::any_cast<t> (_t) << endl << endl;
}
Now this works fine if you know your data type:
Example:
void *mydata = alloca(size_object) ;
void some_function_store_int_data_in_voidpointer( &mydata)
print <int> (mydata); // it's ok .
But this is impractical when you have lots of different datatypes, like this:
void somefunction(args &a , void *dest )
{
/*code returnd data */
}
enum args
{
_INT_ ,
_FLOAT_ ,
_CHARPOINTER_ ,
};
vector <void *test> myvector ;
myvector.resize (3) ;
void somefunction(_INT_ , myvector.at(0) ) ; // store int in void*
void somefunction(CHARPOINTER , myvector.at(0) ) ;// store char* in void*
void somefunction(_FLOAT_ , myvector.at(0) ) ;// store float in void*
print <int> (myvector.at(0));
print <char*> (myvector.at(1));
print <float> (myvector.at(2));
1 - If i use something like this
print <typeid(myvector.at(2))> (myvector.at(2));
i get an error because my data is float and I make it const char*
2 - Perhaps I can pass the type of every value if I have few data. This is OK. But what if I have 100 values from different types!
I am looking for something like: typeid but it' return the type not `const char*.
PART 2
because I have avector I will use a for_each algorithm like this:
for_each ( myvector.begin() , myvector.end() , print</*what i should pass her int , float ,char* ...or what , */>);
In the previous code I can pass only one type to the function so the data from the same type will print. Else the data that are not the same type will print, but completely wrong (Strange format).
So if I pass char* the int data will print completely wrong.
How can I do this differently?
How can I do this differently?
If your intention is to use same function for printing different data formats, then you can do it like this:
#include <iostream>
#include <algorithm>
#include <vector>
template <typename T> class Callback{
public:
void operator()(const T& value) const{
std::cout << value << std::endl;
}
};
template <typename T> Callback<typename T::value_type> makeCallback(const T&){
return Callback<T::value_type>();
}
int main(int argc, char** argv){
std::vector<int> ints(20);
std::vector<float> floats(20);
std::fill(ints.begin(), ints.end(), 0);
std::fill(floats.begin(), floats.end(), 0.0f);
std::for_each(ints.begin(), ints.end(), makeCallback(ints));
std::for_each(ints.begin(), ints.end(), makeCallback(floats));
return 0;
}
However, if you want to store several different data types in same std::vector, then you need "variant" types (like boost::variant, QVariant or similar), and there's no way around it.
I am looking for something like: typeid but it' return the type not `const char*.
In C++ "type" exists only at compilation stage, so you cannot return it, because it no longer exists once program has been compiled. There's no "type", so you can't return it.
So to get a "type" from object you need to implement some kind of "variant" type that can hold any object along with its type information, and pass that "variant" type around. One example of such system is QVariant in Qt 4.
AFAIK implementation of variant type goes like this: there is some kind of table for every type variant supports, you register all types variant class must support in that table. Table provides functions for creating type, destroying type, (de)serializing type, and possibly information about amount of memory required by one object of the type. The table can contain optional information you want, and you can convert entire registration procedure into macros+template combo. As you can see, this is not something that is done automatically by compiler, but something that involves plenty of hassle and must be taken care of by programmer. Also, things get much more fun if program must be able to take types developed externally (in plugins, etc).
As a result of language restrictions, the better idea would be to avoid situations when you need to "return type" when possible - variant systems aren't exactly difficult, but they aren't much fun either, due to all necessary sanity checks and conversions. Example problem: if you pass a string in variant type to a function that is supposed to take a float, should this function attempt to convert string to float? If conversion fails, should it crash/throw exception, or assume that variable has default value? If there's default value for failed conversions, what should it be and how should it be passed? And so on. This isn't a rocket science, but it is quite annoying to deal with.
For example, you could get rid of "void*" (if function takes pointer as an argument, then I would assume that poitner can be NULL/0. So "void*" arguments aren't exactly a good idea). arguments in your functions and use templates to make compiler generate code your want for types you actually use in your program. If templates are not an option, then you need some kind of "variant" type (preferably developed by somebody else), ... or you could switch to another language that provides type information you need. You don't have to use C++, any tool that does the job will do. Relying on RTTI also isn't a perfect solution, becuase if you manage to pass a pointer to something that does NOT contain type information, you'll get a non-standard exception (__non_rtti_object).
If you have a limited list of types you want to support, use boost::variant<int, float, const char*, ...> instead of boost::any (or void*). Then you can define a visitor to call the correct instantiation of the print function.
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
template <class T>
void print(T t)
{
std::cout << t << '\n';
}
struct print_visitor: boost::static_visitor<void>
{
template <class T>
void operator()(T t) const { print(t); }
};
int main()
{
typedef boost::variant<int, double, const char*> Variant;
std::vector<Variant> vec;
vec.push_back(13);
vec.push_back(3.14);
vec.push_back("Hello world");
BOOST_FOREACH(const Variant& v, vec) {
boost::apply_visitor(print_visitor(), v);
}
}
With a void* or a boost::any, I don't think you can do better than use a long if-chain to test all supported types.
C++ is a statically typed language, thus types only really exist in a meaningful way at the compile time, not at runtime. At runtime the best C++ can give you is RTTI which provides you with things like dynamic_cast<> and typeid(), which are however limited to giving you information along the inheritance hierarchy only, i.e. if you have
class Base
class DerivedA : public Base
class DerivedB : public Base
and you have a Base* or Base& you can find out if it's a Base, a DerivedA or a DerivedB. However in your case you only have a void*, which is completely outside of any inheritance hierarchy and thus has no type information associated with it. Thus all typeid() will tell you is that you have a void*, it won't tell you whatever type might hide behind it.
Furthermore a construct like:
print <typeid(myvector.at(2))> (myvector.at(2));
wouldn't work in C++ either, as the type for a template also needs to be known at compile time. Here however the type of .at(2) would only be known at runtime.
So to solve your problem you have to do the type handling yourself. Meaning you have to store the type along with the object you want to store, which would look something like this:
struct Value
{
enum { kInt, kString } type;
union {
int vInt;
char* vChar;
} value;
};
[...]
Value v;
v.type = Value::kInt;
v.value.vInt = 5;
switch(v.type)
{
case Value::kInt:
// do int specific stuff
break;
case Value::kString:
// do string specific stuff
break;
}
The boost::variant<> class that visitor mentioned provides basically the above in a nicely packaged way.
Another thing worth to mention is decltype, decltype is new in C++11 standard and allows you to get the actual type of an object and thus you can write code like:
int a;
decltype(a) b;
Where b gets the same type as a, i.e. int. This sounds exactly like what you want, but it is not, decltype() has the same restrictions as before. It can only work when the type is already known at compile time, it can't do anything with types only known at runtime. Thus it will not work in your situation and is only really useful when doing some more complex template programming.
Long story short, use boost::variant<> or write yourself a class that works in a similar way.
PART 1: I'm not quite sure I fully understand your query, but have you looked at the header file <typeinfo>? struct type_info may be what you're looking for.

Advantage of using default function parameter

int add (int x, int y=1)
int main ()
{
int result1 = add(5);
int result2 = add(5, 3);
result 0;
}
VS
int add (int x, int y)
int main ()
{
int result1 = add(5, 1);
int result2 = add(5, 3);
result 0;
}
What is the advantage of using the default function parameter, in term of execution speed, memory usage and etc? For beginner like me, I sometimes got confused before I realized this usage of default function parameter; isn't it coding without default function parameter made the codes easier to read?
Your add function is not a good example of how to use defaulted parameters, and you are correct that with one it is harder to read.
However, this not true for all functions. Consider std::vector::resize, which looks something like:
template<class T>
struct vector_imitation {
void resize(int new_size, T new_values=T());
};
Here, resizing without providing a value uses T(). This is a very common case, and I believe almost everyone finds the one-parameter call of resize easy enough to understand:
vector_imitation<int> v; // [] (v is empty)
v.resize(3); // [0, 0, 0] (since int() == 0)
v.resize(5, 42); // [0, 0, 0, 42, 42]
The new_value parameter is constructed even if it is never needed: when resizing to a smaller size. Thus for some functions, overloads are better than defaulted parameters. (I would include vector::resize in this category.) For example, std::getline works this way, though it has no other choice as the "default" value for the third parameter is computed from the first parameter. Something like:
template<class Stream, class String, class Delim>
Stream& getline_imitation(Stream &in, String &out, Delim delim);
template<class Stream, class String>
Stream& getline_imitation(Stream &in, String &out) {
return getline_imitation(in, out, in.widen('\n'));
}
Defaulted parameters would be more useful if you could supply named parameters to functions, but C++ doesn't make this easy. If you have encountered defaulted parameters in other languages, you'll need to keep this C++ limitation in mind. For example, imagine a function:
void f(int a=1, int b=2);
You can only use the given default value for a parameter if you also use given defaults for all later parameters, instead of being able to call, for example:
f(b=42) // hypothetical equivalent to f(a=1, b=42), but not valid C++
If there is a default value that will provide correct behavior a large amount of the time then it saves you writing code that constantly passes in the same value. It just makes things more simple than writing foo(SOME_DEFAULT) all over the place.
It has a wide variety of uses. I usually use them in class constructors:
class Container
{
// ...
public:
Container(const unsigned int InitialSize = 0)
{
// ...
}
};
This lets the user of the class do both this:
Container MyContainer; // For clarity.
And this:
Container MyContainer(10); // For functionality.
Like everything else it depends.
You can use it to make the code clearer.
void doSomething(int timeout=10)
{
// do some task with a timeout, if not specified use a reasonable default
}
Is better than having lots of magic values doSomething(10) throughout your code
But be careful using it where you should really do function overloading.
int add(int a)
{
return a+1;
}
int add(int a,int b)
{
return a+b;
}
As Ed Swangren mentioned, some functions have such parameters that tend to have the same value in most calls. In these cases this value can be specified as default value. It also helps you see the "suggested" value for this parameter.
Other case when it's useful is refractoring, when you add some functionality and a parameter for it to a function, and don't want to break the old code. For example, strlen(const char* s) computes the distance to the first \0 character in a string. You could need to look for another characted, so that you'll write a more generic version: strlen(const char* s, char c='\0'). This will reuse the code of your old strlen without breaking compatibility with old code.
The main problem of default values is that when you review or use code written by others, you may not notice this hidden parameter, so you won't know that the function is more powerful than you can see from the code.
Also, google's coding style suggests avoiding them.
A default parameter is a function parameter that has a default value provided to it. If the user does not supply a value for this parameter, the default value will be
used. If the user does supply a value for the default parameter, the user-supplied value is used.
In computer programming, a default argument is an argument to a function that a programmer is not required to specify. In most programming languages, functions may take one or more arguments. Usually, each argument must be specified in full (this is the case in the C programming language)
Advantages of using default parameter, as others have pointed out, is indeed the "clarity" it brings in the code with respect to say function overloading.
But, it is important to keep in mind the major disadvantage of using this compile-time feature of the language: the binary compatibility and default function parameter does not go hand in hand.
For this reason, it is always good to avoid using default params in your API/interfaces classes. Because, each time you change the default param to something else, your clients will need to be recompiled as well as relinked.
Symbian has some very good C++ design patterns to avoid such BC.
Default parameters are better to be avoided.
let's consider the below example
int DoThis(int a, int b = 5, int c = 6) {}
Now lets say you are using this in multiple places
Place 1: DoThis(1);
Place 2: DoThis(1,2);
Place 3: DoThis(1,2,3);
Now you wanted to add 1 more parameter to the function and it is a mandatory field (extended feature for that function).
int DoThis(int a, int x, int b =5, int c=6)
Your compiler throws error for only "Place 1". You fix that. What about other others?
Imagine what happens in a large project? It would become a nightmare to identify it's usages and updating it rightly.
Always overload:
int DoThis(int a) {}
int DoThis(int a, int b {}
int DoThis(int a, int b, int c) {}
int DoThis(int a, int b, int c, int x) {}