-4

In this C++ program the function print_nums doesn't accept the vector<double> numbers as an actual prameter when called in the switch_function and I wanted the add_num function to accept vector as an argument but I think it will cause the same error!

note that the error mentioned doesn't appear in this code but many errors and warnings appear when I compile this code and when I change double min to double minn or double max to double maxx I'm lift with the mentioned error, by the way I'm still a beginner in C++ so please explain why I can't use the words min and max ,also the main error of the function print_nums and any other error or warning.

#include <iostream>
#include <vector>
#include <climits>
#include <cfloat>
using namespace std;
double mean{};
    double min=FLT_MAX;
    double max=FLT_MIN;
vector<double>numbers{};
char select;
char list();
void print_nums(vector<double>&numbers);
void program_func();
double nums_mean(double);
char switch_function(char);
void display_nums_mean(double);
int main(){


   program_func();


        return 0;
}
void program_func(){
    while(select!='q'&&select!='Q'){
       list();
  switch_function(select);

        }
    }
char list(){
     cout<<"Please select an Order\n";
        cout<<"***********************\n";
        cout<<"P-Print numbers\n";
        cout<<"A-Add a number\n";
        cout<<"M-Display the numbers mean\n";
        cout<<"S-Display smallest number\n";
        cout<<"L-Display largest number\n";
        cout<<"Q-Quit\n";
        cout<<"Order " ;
        cin>>select;
        cout<<endl;
    return select;

    }
void print_nums(const vector <double> &numbers){
    if(numbers.size()!=0)
     for(auto value : numbers)
              cout<<value<<endl;
            else
                cout<<"Array is empty"<<endl;

    }
void add_num(){
        cout<<"How many numbers will be added to the list : ";
        unsigned int num_of_nums;
        double num;
        cin>>num_of_nums;
        cout<<endl;
        cout<<"add numbers to the list : ";
        for(unsigned int i=0;i<num_of_nums;i++){
            cin>>num;
            numbers.push_back(num);
            }
        return;
        }
double nums_mean(double mean){
    double sum{};
    for(unsigned int i=0;i<numbers.size();++i){
        sum+=numbers.at(i);

        }
    mean = sum/(numbers.size());


    return mean;


    }
double small_num(double min){
    for(unsigned int i=0;i<numbers.size();++i){

                if(min>=numbers.at(i)){

                    min = numbers.at(i);
                    }

            }
            return min;
    }
double large_num(double max){
    for(unsigned int i=0;i<numbers.size();++i){
                if(max<=numbers.at(i)){

                    max = numbers.at(i);
                }

            }
            return max;

    }
void display_nums_mean(double mean){
    cout<<"The mean of the numbers is : "<<mean<<endl;


    }
void display_nums_min(double min){
    cout<<"The minimum number is : "<<min<<endl;

    }
void display_nums_max(double max){
    cout<<"The maximum number is : "<<max<<endl;
    return;
    }
char switch_function(char select){
    switch(select){
        case 'p':
        case 'P':
                 print_nums(numbers);
                 break;
        case 'a':
        case 'A':
                 add_num();
                 break;
        case 'm':
        case 'M':
                 mean=nums_mean(mean);
                 display_nums_mean(mean);
                 break;
        case 's':
        case 'S':
                 min=small_num(min);
                display_nums_min(min);
                 break;
        case 'l':
        case 'L':
                 max=large_num(max);
                 display_nums_max(max);
                 break;
        case 'q':
        case 'Q':
         return select;
        default:
         cout<<"Please Enter a valid character "<<endl;


    }

    return select;   
    }
  • `const vector &` isn't the same as `vector &` – πάντα ῥεῖ Jul 03 '18 at 16:28
  • Why do you initialize a `double` with `FLT_MAX`? There is a `DBL_MAX` too. – DeiDei Jul 03 '18 at 16:32
  • @DeiDei I didn't know :( I thought there was only `FLT_MAX` but the error still appears – Abdullah Zareaa Jul 03 '18 at 16:38
  • 9
    You use `using namespace std;` (get out of that habit) which means that `std::min` and `std::max` are pulled in from the `std` namespace into the global namespace. – Jesper Juhl Jul 03 '18 at 16:45
  • @AbdullahZareaa Your code still suffers from the mismatching function signatures of the `print_nums()` function in declaration and definition as I mentioned in my 1st comment. – πάντα ῥεῖ Jul 03 '18 at 16:48
  • @Rakete1111 how is that a duplicate answering OPs question of "why I can't use the words min and max as variable names?"? Voting to reopen. – Jesper Juhl Jul 03 '18 at 16:51
  • 1
    @Rakete1111: I disagree with the duplicate. The question you've linked to is very general and will be nearly impossible for a beginner to find this specific problem among its 27 answers. There are two common reasons why `min` and `max` in particular are common problems in C++, and only one of them is even described among those answers. – Adrian McCarthy Jul 03 '18 at 16:51
  • "error" ... what error? BTW terrible style of code. Suggest learn on simple cases. – Jacek Cz Jul 03 '18 at 16:55
  • @AdrianMcCarthy Did you inspect the questions edit history? – πάντα ῥεῖ Jul 03 '18 at 16:56
  • Why the flurry of global variables? – Jesper Juhl Jul 03 '18 at 16:56
  • Maybe look into clang format to format your code in a readable manner. – Jesper Juhl Jul 03 '18 at 16:57
  • I have searched some, but I have found std::min (and std::max) only in , which, appears to be missing from the includes of the post. If you were to compile using the option -E, the output should enable you to find all the origins of std::min/std::max pulled in with your compile, with a single grep (or editor search). This would help you understand by you should not have "using namespace std;" and perhaps suggest a solution (like maybe do not include < algorithm >) – 2785528 Jul 03 '18 at 17:53
  • @2785528 even if *direct* includes don't pull in the symbol, transitive includes might. – Jesper Juhl Jul 03 '18 at 19:06
  • I found std::min (and std::max) defined in [ /usr/include/c++/7/bits/stl_algobase.h ] which was chain included (3 steps) from [ /usr/include/c++/7/iostream ]. on Ubuntu 17.10, g++ v7.2.0 – 2785528 Jul 04 '18 at 15:03

3 Answers3

4

You use using namespace std; (get out of that habit) which means that std::min and std::max are pulled in from the std namespace into the global namespace. That is why you can't then use those names in your own code, since they have already been defined.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • And be aware of OPs upcoming next complaint regarding the original question tile. – πάντα ῥεῖ Jul 03 '18 at 17:01
  • It was the original _due course_ of the question (and why it was already closed). And your answer doesn't fix all of the problems in the code. – πάντα ῥεῖ Jul 03 '18 at 19:12
  • @πάντα ῥεῖ I didn't *try* to fix *all* problems in the code. I merely tried to answer the original question of "why I can't use the words min and max as variable names?". One problem at a time. – Jesper Juhl Jul 03 '18 at 19:14
0

I'm still a beginner in C++ so please explain why I can't use the words min and max...

you can!

Section one (below) demonstrates (in minimal code) what is happening.

Section two shows a 'solution' (below).

Bonus - third section solves using C++ class.


1) The first of two coding choices is a [MCVE] (which you should recognize its origins) that recreates the ambiguity (and thus the error) that this choice causes.

// this first section matches your code, 
#include <iostream>
#include <vector>
#include <climits>
#include <cfloat>

using namespace std;    
// this 'using' pulls a 'min' and 'max' (probably functions) 
//   from some std:: declaration 

double min  = FLT_MAX; 
double max  = FLT_MIN;
// ----^^^----  and now these 2 items create two ambiguity's because 
// at this point, the compiler can no longer distinguish 
// between the two min's (or max's).

void program_func(int argc, char* argv[]) {
   std::cout << "\n  " << argc
             << "  "   << argv[0]
             << "\n  " << min  // error: reference to ‘min’ is ambiguous
             << "  "   << max  // error: reference to ‘max’ is ambiguous
             << std::endl;
}    
int main(int argc, char* argv[]) {
   program_func();
   return 0;
}

2) For your consideration, another (as yet unmentioned) 'solution' to your dilemma (in MCVE form) is to move your code, as simply as possible, into a 'distinguishing' namespace. This action can be accomplished quite easily:

#include <iostream>
#include <vector>
#include <climits>
#include <cfloat>

using namespace std;    
// this 'using' pulls a 'min' and 'max' (probably functions) 
//   from some std:: declaration (as previous)


// now place all of **your** code (except main()) into a distinguishing namespace. 


namespace AZ // (your initials, if you are not already using them ;)
{
   double min  = FLT_MAX;  // these are now AZ::min
   double max  = FLT_MIN;  //           and AZ::max - unambiguous!

   void program_func(int argc, char* argv[])
   {
      std::cout << "\n  " << argc
                << "  "   << argv[0]
                << "\n\n  " << min  // reference to AV::min
                << "  "     << max  //    and       AV::max
                << std::endl;
   }

}  // namespace AZ end 

int main(int argc, char* argv[])
{
   AZ::program_func(argc, argv);  // NOTE AZ:: namespace qualifier!
   return 0;
}

This section compiles and runs with no errors.


The symbols no longer 'clash', and AZ::min and AZ::max are unique and distinguishable with respect to the std::min and std::max.

Note1: This should be sufficient motivation to make the choice to not use the line: "using namespace std;".

Note2: If you keep the line "using namespace std;", do not place it inside of your distinguishing namespace wrapper (AV).

Yes - it is still possible to access std::, within your distinguishing namespace, they are referred to as std::min and std::max.


main error of the function print_nums

Perhaps there is a 2nd worthwhile question to submit. Work on your MCVE, and practice with the SO tools. You can earn points with questions (and the down-votes are contributors asking you for more practice!).

I want to emphasize to you the "M" of mcve. Is the 'print_nums' error even related to the first question?

and any other error or warning.

Generally, 'help debug my code' is not appropriate for this site.


3) Yet another (as yet unmentioned) 'solution' to your dilemma is to move your code, as simply as possible, into a 'distinguishing' class.

You have marked this code as C++. IMHO, the key feature of C++ is class. Thus I advice beginners to focus their effort on creating and using classes, and learning the libraries provided (< vector >, < string >, < iostream >, < iomanip >, < sstream > etc. I further advise to avoid writing C style code (with a few C++ classes), this early training is the time to break any misleading habits.

Using a distinguishing class:

#include <iostream>
#include <vector>
#include <climits>
#include <cfloat>

using namespace std;    

class AZ_t // suffix '_t' because a class defines a type
{
   double min  = FLT_MAX;  // these are now AZ_t::min
   double max  = FLT_MIN;  //           and AZ_t::max - unambiguous!

   int program_func(int argc, char* argv[])
   {
      std::cout << "\n  " << argc
                << "  "   << argv[0]
                << "\n\n  " << min  // reference to AZ_t::min
                << "  "     << max  //    and       AZ_t::max
                << std::endl;
   }

   // NOTE3 - see below

 public: // above this statement is private
   // a functor is easy to use, but it needs one more function:

   int operator()(int argc, char* argv[]) { 
       return program_func(argc, argv);   
   }

};  // class AZ end 

int main(int argc, char* argv[]) // main is now 1/2 the size
{
   return AZ_t()(argc, argv);   // because this functor is a 1 liner!
   //           ^^^^^^^^^^^^ -- parameter to operator() 
   //     ^^^^^^ -- instance ctor  (constructor)
   // ^^^ -- operator() returns int
   // instance dtor (destructor) runs when 1 liner is complete
}

This section compiles and runs with no errors.


NOTE3: At this point in the class AZ_t is the location for the rest of your code. One nice thing about coding 'in a class' is that you do not need function forwarding. (Your post has about 6 forwards -- evidence of c-style code) Simply present the function in any order (the compiler figures it out), but I recommend you try for the most readable sequence.

2785528
  • 5,438
  • 2
  • 18
  • 20
0

The line using namespace std says that you include std namespace. By including this you are including a lot of functions and variables in this namespace.

When you use any variables, if a variable with the same name exists in namespace std it will be tied up to it. Now by declaring another variable in your code the compiler is confused which one the coder is referring to.

Try to use more meaningful names for your variables max_num and min_num. If you still want to use max and min, declare them in a user defined namespace and refer to them in your code.

Shrikanth N
  • 652
  • 3
  • 17