Error ostream in namespace std does not name a type

  • Forum
  • General C++ Programming
  • Linking error on overloaded operator<<

Linking error on overloaded operator<<

I have been writing a small static library with a Jeton class. This class has an overloaded operator<<. Here is the code:

In Jeton class:

Jeton.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace pXbase{

class Jeton
{
public:
    // Some stuff...

    friend std::ostream& operator<<(std::ostream& p_flux, const Jeton& p_jeton);

private:
    Couleur m_couleur;
};

} // namespace pXbase 

Jeton.cpp:

1
2
3
4
5
6
7
8
9
10
11
using namespace pXbase;
using namespace std;

//Some stuff...

ostream& operator<<(ostream& p_flux, const Jeton& p_jeton)
{
    p_flux << " " << p_jeton.imprimerCodeConsole() << " "; // The method returns a char.

    return p_flux;
}

And finally, main.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "Jeton.h"

using namespace pXbase;
using namespace std;

int main()
{
    Jeton jeton;

    cout << jeton;

    return 0;
}

When I compile this, I get the following liker error:


undefined reference to `pXbase::operator<<(std::ostream&, pXbase::Jeton const&)'

I have carefully looked at the code but found nothing that could generate this error… My library is correctly liked to the main since every other method work. Can anyone tell me what is wrong with this?

Thanks!

Last edited on

Try enclosing the code in file Jeton.cpp inside the namespace pXbase.

@Chervil: Thanks, it did work with your suggestion. But… what’s going on here? It did enclose the operator in the pXbase namespace upon declaration. Why do I have to do it it at definition as well?

I’m not sure of the proper technical explanation, however, as you said, the function was declared within that namespace, so it seems reasonable that the definition should be too. Otherwise it would belong to the global namespace.

Ok thanks!

@BobMorane: I was trying to replicate your code and am getting error messages from the header and implementation files compilations:

error: 'ostream' in namespace 'std' does not name a type

I think I understand why this is happening, at least in the header file — Jeton is enclosed entirely within namespace pXbase and therefore cannot reach namespace std despite the scope resolution std::ostream. Did you face any similar issues?

@gunnerfunner: Thanks for the check. I did not see that error message here. After I applied Chervil’s suggestion, everything compiled/linked fine. Also, I think it’s worth mentioning that my compiler (gcc) is set to see warning as errors.

Personnaly,

Jeton is enclosed entirely within namespace pXbase and therefore cannot reach namespace std despite the scope resolution std::ostream.

I don’t think this should be. You can refer to other namespaces inside a particular namespace. Maybe I don’t understand your point precisely?

Thanks

Last edited on

@gunnerfunner

Did you put #include <iostream> at the start of Jeton.h ?

No, I knew #include <iostream> might be a possible solution but did not want to do that in the header file. But it seems OP managed to get by w/o it

@gunnerfunner: is it working now?

Well, if the header uses something like std::ostream then it must have the <iostream> header available. I can’t see a problem with putting it at the start of «Jeton.h», but if you don’t, you need to make sure that whichever file makes use of header «Jeton.h» first includes the required standard headers.

if the header uses something like std::ostream then it must have the <iostream> header available … not always but in this case, sure because of namespace pXbase. I was just wondering if we could do w/o including the whole library in the header but it seems we can’t for this example

The program won’t compile if there is a reference to std:: something without having the corresponding header available somewhere. Sometimes one header includes another, so it isn’t always obvious which headers are visible.

User-defined headers are generally included inside another file, which might incidentally include some other headers, but one way or another that’s the only way it can compile.

> I was just wondering if we could do w/o including the whole library in the header

To minimise dependencies:

In the header:

#include <iosfwd>

and declare the functions

In the implementation file:

#include <iostream>

(plus

#include <fstream>

etc. as required) and define the functions.

eg. header file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// #include guard 
#include <iosfwd>

namespace A
{
    struct B
    {
        B() = default ;
        B( std::ifstream& ) ;

        int v = 7 ;
        // ...
        friend std::ostream& operator<< ( std::ostream& stm, const B& b ) ;
    };
}

implementation file:

1
2
3
4
5
6
7
8
9
10
11
// #include "header file"
#include <iostream>
#include <fstream>

namespace A
{
    B::B( std::ifstream& file ) { if( !( file >> v ) ) { /* throw something */ }}

    std::ostream& operator << ( std::ostream& stm, const A::B& b )
    { return stm << "B{ " << b.v << " }n" ; }
}

@JLBorges: Brilliant! Thank you

Topic archived. No new replies allowed.

Просто попал в C ++ и у меня есть быстрый вопрос.

После компиляции с

g++ *.cpp -o output

Я получаю эту ошибку:

error: 'ostream' in 'class Dollar' does not name a type

Это мои три файла:

main.cpp

#include <iostream>
#include "Currency.h"#include "Dollar.h"
using namespace std;

int main(void) {
Currency *cp = new Dollar;

// I want this to print "printed in Dollar in overloaded << operator"cout << cp;
return 0;
}

Dollar.cpp

#include <iostream>
#include "Dollar.h"
using namespace std;

void Dollar::show() {
cout << "printed in Dollar";
}

ostream & operator << (ostream &out, const Dollar &d) {
out << "printed in Dollar in overloaded << operator";
}

Dollar.h

#include "Currency.h"
#ifndef DOLLAR_H
#define DOLLAR_H

class Dollar: public Currency {
public:
void show();
};

ostream & operator << (ostream &out, const Dollar &d);

#endif

Спасибо за ваше время, и все помогает!

2

Решение

У вас есть несколько ошибок в коде.

  1. Вы интенсивно используете using namespace std, Это плохая практика. В частности, это привело к ошибке, с которой вы столкнулись: у вас нет using namespace std в Dollar.hТаким образом, компилятор понятия не имеет, что ostream средства. Либо поставить using namespace std в Dollar.h тоже, или лучше просто прекратить использовать его и указать std пространство имен напрямую, как в std::ostream,
  2. Ты используешь std::ostream в ваших заголовках, но вы не включаете соответствующий стандартный заголовок библиотеки <ostream> в них (<ostream> содержит определение std::ostream учебный класс; для полной библиотеки ввода / вывода включить <iostream>). Хорошей практикой является включение всех зависимостей заголовка в сам заголовок, чтобы он был автономным и мог быть безопасно включен где угодно.
  3. Вы реализуете оператор вывода потока с подписью std::ostream & operator << (std::ostream &, Dollar const &), что совершенно справедливо. Тем не менее, вы называете это для указатель печатать Dollar, Вы должны скорее назвать это с объект сам по себе, а не указатель, поэтому вы должны разыменовать указатель: std::cout << *cp;,
  4. Вы реализовали оператор вывода для Dollar класс, но используйте его для переменной типа Currency: это не сработает. Есть способ сделать это — существуют виртуальные методы именно по этой причине. Однако в этом случае оператор является свободной функцией, поэтому он не может быть виртуальным. Итак, вам, вероятно, следует добавить виртуальный print метод к вашему Currency класс, реализовать его в Dollarи вызвать его из оператора вывода:

    #include <iostream>
    
    class Currency {
    public:
    virtual void print (std::ostream &) const = 0;
    };
    
    class Dollar : public Currency {
    void print (std::ostream & out) const override {
    out << "A dollar";
    }
    };
    
    std::ostream & operator << (std::ostream & out, Currency const & c) {
    c.print(out);
    return out;
    }
    
    int main(/* void is redundant here */) {
    Currency *cp = new Dollar;
    std::cout << *cp;
    // return 0 is redundant in main
    }
    

6

Другие решения

Вам нужно #include <iostream> в пределах Dollar.h, чтобы ваш std::ostream & operator разрешается компилятором.

0

4 / 4 / 2

Регистрация: 27.03.2013

Сообщений: 110

1

12.01.2014, 16:28. Показов 6866. Ответов 3


C++
1
friend ostream& operator<<(ostream&, const string&);

— вот эта строка.
Весь код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
            #include <iostream>
            #include <string.h>
            #include <fstream>
 
            class string {
               struct srep {
                 char* s;       // ????????? ?? ??????
                 int n;         // ??????? ????? ??????
                 srep() { n = 1; }
               };
               srep *p;
 
            public:
              string(const char *);   // string x = "abc"
              string();               // string x;
              string(const string &); // string x = string ...
              string& operator=(const char *);
              string& operator=(const string &);
              ~string();
              char& operator[](int i);
 
              friend ostream& operator<<(ostream&, const string&);
              friend istream& operator>>(istream&, string&);
 
              friend int operator==(const string &x, const char *s)
                { return strcmp(x.p->s,s) == 0; }
 
              friend int operator==(const string &x, const string &y)
                { return strcmp(x.p->s,y.p->s) == 0; }
 
              friend int operator!=(const string &x, const char *s)
                { return strcmp(x.p->s,s) != 0; }
 
              friend int operator!=(const string &x, const string &y)
                { return strcmp(x.p->s,y.p->s) != 0; }
           };
            string::string()
           {
             p = new srep;
             p->s = 0;
           }
 
           string::string(const string& x)
           {
             x.p->n++;
             p = x.p;
           }
 
           string::string(const char* s)
           {
             p = new srep;
             p->s = new char[ strlen(s)+1 ];
             strcpy(p->s, s);
           }
 
           string::~string()
           {
             if (--p->n == 0) {
                delete[]  p->s;
                delete p;
             }
           }
           string& string::operator=(const char* s)
          {
            if (p->n > 1) {  // ????????????? ?? ?????? ??????
                p->n--;
                p = new srep;
            }
            else    // ??????????? ?????? ?? ?????? ?????????
                delete[] p->s;
 
            p->s = new char[ strlen(s)+1 ];
            strcpy(p->s, s);
            return *this;
          }
 
          string& string::operator=(const string& x)
          {
            x.p->n++;  // ?????? ?? ?????? ``st = st''
            if (--p->n == 0) {
               delete[] p->s;
               delete p;
            }
            p = x.p;
            return *this;
          }
          ostream& operator<<(ostream& s, const string& x)
          {
             return s << x.p->s << " [" << x.p->n << "]n";
          }
          istream& operator>>(istream& s, string& x)
          {
             char buf[256];
             s >> buf;   // ненадёжно, возможно переполнение buf
             x = buf;
             cout << "echo: " << x << 'n';
             return s;
          }
           void error(const char* p)
          {
            cerr << p << 'n';
            exit(1);
          }
 
        char& string::operator[](int i)
        {
         if (i<0 || strlen(p->s)<i) error("недопустимое значение индекса");
           return p->s[i];
        }
        int main()
         {
           string x[100];
           int n;
 
           cout << " здесь начало n";
 
           for ( n = 0; cin>>x[n]; n++) {
               if (n==100) {
                  error("слишком много слов");
                  return 99;
               }
               string y;
               cout << (y = x[n]);
               if (y == "done") break;
 
           }
           cout << "теперь мы идем по словам в обратном порядке n";
           for (int i=n-1; 0<=i; i--) cout << x[i];
           return 0;
         }

Ну, так же там есть подобные ошибки.
Лог:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
22  22  D:Проекты с++ООПЛБ 3, В 8main.cpp [Error] 'ostream' does not name a type
23  22  D:Проекты с++ООПЛБ 3, В 8main.cpp [Error] 'istream' does not name a type
87  11  D:Проекты с++ООПЛБ 3, В 8main.cpp [Error] 'ostream' does not name a type
91  11  D:Проекты с++ООПЛБ 3, В 8main.cpp [Error] 'istream' does not name a type
D:Проекты с++ООПЛБ 3, В 8main.cpp In function 'void error(const char*)':
101 13  D:Проекты с++ООПЛБ 3, В 8main.cpp [Error] 'cerr' was not declared in this scope
101 13  D:Проекты с++ООПЛБ 3, В 8main.cpp [Note] suggested alternative:
1   0   D:Проекты с++ООПЛБ 3, В 8main.cpp In file included from main.cpp
63  18  c:program files (x86)dev-cppmingw64libgccx86_64-w64-mingw324.7.1includec++iostream    [Note] 'std::cerr'
102 19  D:Проекты с++ООПЛБ 3, В 8main.cpp [Error] 'exit' was not declared in this scope
D:Проекты с++ООПЛБ 3, В 8main.cpp In function 'int main()':
115 12  D:Проекты с++ООПЛБ 3, В 8main.cpp [Error] 'cout' was not declared in this scope
115 12  D:Проекты с++ООПЛБ 3, В 8main.cpp [Note] suggested alternative:
1   0   D:Проекты с++ООПЛБ 3, В 8main.cpp In file included from main.cpp
62  18  c:program files (x86)dev-cppmingw64libgccx86_64-w64-mingw324.7.1includec++iostream    [Note] 'std::cout'
117 25  D:Проекты с++ООПЛБ 3, В 8main.cpp [Error] 'cin' was not declared in this scope
117 25  D:Проекты с++ООПЛБ 3, В 8main.cpp [Note] suggested alternative:
1   0   D:Проекты с++ООПЛБ 3, В 8main.cpp In file included from main.cpp
61  18  c:program files (x86)dev-cppmingw64libgccx86_64-w64-mingw324.7.1includec++iostream    [Note] 'std::cin'

Подскажите, пожалуйста, где, что, как?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Понравилась статья? Поделить с друзьями:
  • Error orpsim 16407 missing model
  • Error orpsim 16103 invalid value
  • Error org springframework web servlet dispatcherservlet context initialization failed
  • Error org springframework web context contextloader context initialization failed
  • Error org springframework boot springapplication application run failed утм