-1

The uppercase() function is part of my class:

class MyString {
public:
    MyString();
    MyString(char cstring[]);
    void uppercase();

private

};

And the implementation for uppercase is not finished, but looks like this:

void MyString::uppercase()
{
    cout << "need to implement";
}

When I call the function, it looks like this:

//Output streaming Operator Overload
ostream& operator<<(ostream& os, const MyString& string)
{
    if (MyString::printAsUppercase == true)
        uppercase();
    else
        os << string.data;

    cout << "(" << string.length << ")";
    return os;

}

When I attempt to compile the code, I receive the following error:

'std::uppercase': function does not take 0 arguments

I really don't understand this, as I declared the prototype to NOT take any arguments, and followed through with that in the implementation. The function shouldn't have to take any arguments. Why does this happen?

Gabriel
  • 1,922
  • 2
  • 19
  • 37
Dima
  • 27
  • 1
  • 8
  • 6
    And this is why you [do not use `using namespace std;`](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – NathanOliver Jan 26 '17 at 19:05
  • 1
    Note the difference between your `MyString::uppercase` and the compilers request for `std::uppercase`. The poor compiler is confused and is calling the wrong function. – user4581301 Jan 26 '17 at 19:18
  • You have a few problems on your hand there: 1) `using namespace std;` 2) naming the argument "string" (like the std type - bound to cause trouble) 3) naming your function identical to the `std::uppercase`. – Jesper Juhl Jan 26 '17 at 19:45
  • Your `operator<<` function is a friend function and has no notion of `uppercase` being a function of `MyString` in your example (because you do not call `string.uppercase()` or anything like that). I am fairly sure that if you actually called it like a method, it would compile and work. – callyalater Jan 26 '17 at 20:02
  • It does work, but ONLY if I remove "const" from the function arguments. Otherwise, there's an error, because my "string" object does not match my "const string" object. Any thoughts? – Dima Jan 26 '17 at 21:45

3 Answers3

1

std::uppercase is a legitimate I/O stream object in the standard library. Because you are coding in the std namespace, the compiler cannot tell if you are using your function or the library object. One simple solution is change the name of your function or specify your class MyClass::uppercase(...). A better solution would be to wrap your code in your own namespace or avoid coding in the std namespace with the declaration "using namespace std;" In my opinion, it more clear to specify the std namespace each time it is used. For example, instead of writing "using namespace std;" then "cout << ..." just write "std::cout << ..."

JimK
  • 43
  • 7
  • Got it thanks! I specified that I'm using my class, but it wants a specific reference to an object. So I specified the object instead, but it's incompatible with the object type because I specified "const" in the function prototype, since that's the standard streaming operator overload syntax. Is it okay to remove "const"? – Dima Jan 26 '17 at 19:56
  • @Dima It is considered bad practice to modify/mutate an object that is passed into a stream operator. The main reason being that it would not produce the same results on subsequent function calls. You could add another method to your class to return an uppercase string without modifying the original or use a function to change a copy of the retrieved string. – callyalater Jan 26 '17 at 20:14
0

You need to specify that you want to call your uppercase method. The Error states that you want to call "std::uppercase" << std:: you need to call your method on your class.

Comment edit: François Andrieux mentioned that this is likely a problem because you use "using namespace std;" Therefore all function calls will be searched in the std. (And hes right with that :) )

Flocke
  • 1,004
  • 17
  • 23
  • Perhaps this answer would be improved if it also mentioned that this problem is likely a symptom of `using namespace std;` – François Andrieux Jan 26 '17 at 19:07
  • When I specify "MyString::uppercase()" I get the following error: A nonstatic member reference must be relative to a specific object. And I can't specify it as "string.uppercase()" because the string type is const and cannot be changed, which is what the uppercase() function seems to want to do to the string. – Dima Jan 26 '17 at 19:31
  • @Dima of course you do, because what you want is not to call a static MyString::uppercase(), but string.uppercase(). You need to read a bit more in your C++ books to learn about namespaces, static member functions, scopes,, reserved names/name clashes and C++ in general. Happy studying :) – Jesper Juhl Jan 26 '17 at 19:51
  • Also research name lookup. – Jesper Juhl Jan 26 '17 at 20:03
  • @JesperJuhl Thank you! I've also tried string.uppercase(), but it's incompatible with the object type in the function argument, since that is a "const string" type. – Dima Jan 26 '17 at 21:49
0

I hope the following code could help understanding the points indicated by other users. It compiles, but... definitely it's far from optimal:

main.cpp

#include <iostream>
#include "MyString.h"

int main(int argc, char** argv)
{
   // Needs arguments from command line!!!
   MyString teststring(argv[1]);
   std::cout << teststring << std::endl;
   return 0;
}

MyString.h

class MyString {
public:
   MyString();
   MyString(char *cText);
   void myUpperCase();
   int myStringLenght();

protected:
   bool printAsUppercase;
   char *data;
   friend std::ostream& operator<<(std::ostream& os, 
                                    MyString mystring);
};

MyString.cpp

#include <cstdlib>
#include <cstring>
#include <iostream>
#include "MyString.h"

MyString::MyString(char *cText)
{
   data = (char *)std::malloc(strlen(cText));
   std::strcpy(data, cText);
}

void MyString::myUpperCase()
{
   std::cout << "not yet implemented";
}

int MyString::myStringLenght()
{
   return int(strlen(data));
}

std::ostream& operator<<(std::ostream& os, 
                           MyString mystring)
{
   // to be deleted - only for testing
   mystring.printAsUppercase = true;

   if (mystring.printAsUppercase == true)
      mystring.myUpperCase();
   else
      os << mystring.data;

   std::cout << "(" << mystring.myStringLenght() << ")";
   return os;
}