-1

I am trying to write a class for rational numbers. So far it looks as follows:

#include <iostream>


template <typename T>
class Rational {
    public:
        Rational();
        Rational(T a);
        Rational(T a, T b);
        std::string to_string();
    private:
        T num_;
        T denom_;
};

Rational::Rational(){
   num_ = 0;
   denom_ = 1;
}

Rational::Rational(T a){
    num_ = a;
    denom_ = 1;
}

Rational::Rational(T a, T b) {
    num_ = a;
    denom_ = b;
}

std::string Rational::to_string() {
    return std::to_string(num_) + "/" + std::to_string(denom_);
}

int main() {
    typedef Rational<int> R;
    R r1, r2(2), r3(3, 4);
    std::cout << r1.to_string() + "\n" << r2.to_string() + "\n" << r3.to_string() << std::endl;
    return 0;
}

As you can see, I want to use a template parameter that allows to choose the type of the numbers via:

typedef Rational<int> R;

I tried to follow the instructions from https://riptutorial.com/cplusplus/example/14397/member-types-and-aliases, but unfortunately it doesn't work yet. I get the following error message:

rational.cpp:25:1: error: 'Rational' is not a class, namespace, or enumeration
Rational::Rational(){
^
rational.cpp:14:7: note: 'Rational' declared here
class Rational {
      ^
rational.cpp:30:1: error: 'Rational' is not a class, namespace, or enumeration
Rational::Rational(T a){
^
rational.cpp:14:7: note: 'Rational' declared here
class Rational {
      ^
rational.cpp:30:20: error: unknown type name 'T'
Rational::Rational(T a){
                   ^
rational.cpp:35:1: error: 'Rational' is not a class, namespace, or enumeration
Rational::Rational(T a, T b) {
^
rational.cpp:14:7: note: 'Rational' declared here
class Rational {
      ^
rational.cpp:35:20: error: unknown type name 'T'
Rational::Rational(T a, T b) {
                   ^
rational.cpp:35:25: error: unknown type name 'T'
Rational::Rational(T a, T b) {
                        ^
rational.cpp:40:13: error: 'Rational' is not a class, namespace, or enumeration
std::string Rational::to_string() {
            ^
rational.cpp:14:7: note: 'Rational' declared here
class Rational {
      ^
7 errors generated.

Can anyone point out, where I am going wrong?

spadel
  • 998
  • 2
  • 16
  • 40
  • 1
    What do you mean by "it doesn't work yet"? Please clarify the issues you're facing. – cigien Mar 12 '21 at 14:23
  • Sorry - I edited. – spadel Mar 12 '21 at 14:25
  • 3
    Your issue is with the definition of methods, missing `template ` and `` [Fixed code](http://coliru.stacked-crooked.com/a/024cc2e5889d9238). – Jarod42 Mar 12 '21 at 14:25
  • That particular tutorial concerns type aliases as members and is completely irrelevant, so it's not surprising that it didn't help. What part exactly do you think that you're following? – molbdnilo Mar 12 '21 at 14:26
  • 3
    `rational.cpp`? Seems like this will be next thing to fix: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – Lukas-T Mar 12 '21 at 14:27
  • Does this answer your question? [template and derived class definition : error: 'myClass' is not a class, namespace, or enumeration](https://stackoverflow.com/questions/34803311/template-and-derived-class-definition-error-myclass-is-not-a-class-namespa) – JaMiT Mar 12 '21 at 14:28
  • Thanks a lot for your help guys!! :) I recently started with C++ and it is still a bit confusing - sorry if the question was obvious to you guys. – spadel Mar 12 '21 at 14:29
  • 1
    This is at least the second question you've asked very recently about class templates. While there are canonical targets for each of those questions, note that you're wasting other users' time by not learning this from an external resource. I strongly suggest trying to understand these concepts and only asking a question when you've tried for a while to solve the problem. SO is not really a tutorial website, and using it as such is not going to work out well for you. – cigien Mar 12 '21 at 14:30
  • @cigien I asked the same question 20 minutes ago, but it was closed with a reference to another stackoverflow post, that was not helpful at all. As you can see, I was trying to get to a solution myself, but it wasn't working.The given answer is more helpful than any tutorial website that I could have found, because it exactly points out to the part I was not fully understanding. Thanks for your clarification though. – spadel Mar 12 '21 at 14:34
  • Note that there are no known good online C++ tutorials, and C++ is very hard to guess your way around in. Get a [good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – molbdnilo Mar 12 '21 at 14:36
  • I don't think cigien wanted to discourage you in any way. The thing is just that templates is a rather broad and deep topic, you will struggle a lot without some book. Definition of class template methods should be covered in an introduction to class templates. – 463035818_is_not_an_ai Mar 12 '21 at 14:37
  • 1
    I don't understand. This is the [target](https://stackoverflow.com/questions/15049795) I used to close your previous [question](https://stackoverflow.com/questions/66601062). If you see bullet#4 in the first answer to that target question, it covers *exactly* what you're missing in this question, and is what the provided answer covers here. Please take the time to read the targets that are used to close your question, before assuming that it's not helpful. – cigien Mar 12 '21 at 14:37
  • Alright I apologize - I see it now. I couldn't identify that as my answer since I am not too familiar with the terminology yet. – spadel Mar 12 '21 at 14:41
  • No worries. Thanks for understanding. I agree that the terminology is hard, and templates in C++ are generally tricky. Mostly, I'm trying to point out that you should put in reasonably more effort into trying to figure out the answer yourself before posting a question. My personal metric is about 2 hours of research before posting a question, and even that might be too little time. – cigien Mar 12 '21 at 14:44

1 Answers1

3

As the compiler tries to tell you Rational is not a class. Hence this is wrong:

Rational::Rational(){
   num_ = 0;
   denom_ = 1;
}

If you want to define a method of a class template you need to declare that it is a method of a class template:

template <typename T>
Rational<T>::Rational(){
   num_ = 0;
   denom_ = 1;
}

And same for all other method definitions.

Rational is just a template. Rational<T> is a class. There is only a tiny quirk to remember: Inside the definiotion of Rational<T> you can use Rational to refer to Rational<T>, eg:

template <typename T>
Rational<T>::foo(){
   Rational<T> some_other_instance;
   Rational another_instance;
}
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185