Newsgroup: it.comp.lang.c++
Titolo: using namespace std

E' possibile usarlo in un header file in modo sicuro?
Ho provato a scriverlo all'interno della definizione di una classe, ma 
il compilatore non lo accetta.
Kiuhnm


Il linguaggio non ti vieta di usarlo in un header.
Ma è una pessima cosa in quanto qualunque programma includa quell'header 
è obbligato ad avere tutte le dichiarazioni del namespace std in global 
scope.
Se lo fai in un cpp, allora puoi controllare la cosa (perché il cpp lo 
scrivi tu e non influisce su altri file). Naturalmente devi metterlo 
DOPO i vari include (altrimenti influisce sugli include che lo seguono).
Se lo fai in un header, non puoi controllare gli effetti perché 
l'header, in quanto tale, influisce anche su altri file (tutti i cpp che 
lo includono e ANCHE tutti gli header che vengono inclusi DOPO a quello, 
alcuni dei quali potrebbero benissimo non gradire la cosa).
Invece non puoi (e non ha senso) usarlo all'interno di una classe.

 Invece non puoi (e non ha senso) usarlo all'interno di una classe.
Quindi sono una persona insensata. Pazienza...
Perché non mi spieghi il motivo dell'insensatezza?
Kiuhnm


In effetti io non sono convinto che sia insensato, soprattutto se usi
molti tipi standard nell'interfaccia delle tue funzioni membro o tra i
membri dati della tua classe.
Piuttosto il problema e' che la definizione della tua classe
risulterebbe fragile rispetto al contenuto degli header inclusi prima
del tuo.
Ciao,
Nicola

 del tuo.
Fragile in che senso e perché? (Non è polemico: proprio non capisco cosa 
vuoi dire.)
Kiuhnm


Supponi di avere un file come questo:
// A.h
// Fuori dalla classe perche' dentro non ci puo' stare
using namespace std;
class A {
  vector<int> v;
};
// Fine A.h
e in una libreria che ti interessa usare qualcuno ha scritto:
// my.h
namespace my {
  template <typename T> class vector {};
}
using namespace my;
// fine my.h
Tu scrivi il tuo sorgente come
#include "my.h"
#include "A.h"
int main() {
  A a;
}
e la tua classe A si rompe. Se poi usi funzioni inline puo' andare
anche peggio. Il programma che segue mi stampa 0 col compilatore Comeau
e 2 con g++ 3.4.2; perche'? ;-)
#include <vector>
#include <iostream>
namespace my {
int * find(int * b, int * e, int d) {
  return b + d < e ? b + d : e;
}
}
using namespace my;
using namespace std;
class A {
  public:
    A() {
      d.push_back(2);
      d.push_back(3);
    }
    int get(int v) {
      vector<int>::iterator i = find(d.begin(), d.end(), v);
      return i != d.end() ? *i : 0;
    }
  private:
    vector<int> d;
};
int main() {
  A a;
  cout << a.get(2) << '\n';
}
Ciao,
Nicola

 e 2 con g++ 3.4.2; perche'? ;-)
Accade perché i due compilatori scelgono find() diverse. Il VC 8 invece 
dà errore a priori perché non accetta la conversione da iterator a int *.
Kiuhnm

 dà errore a priori perché non accetta la conversione da iterator a int *.
Solo che sia Comeau che g++ si comportano correttamente, mentre VC8
sbaglia ;-)
Ciao,
Nicola Musatti

 puo' "romperla".
Fammi un esempio.
Kiuhnm

 puo' "romperla".
Ovviamente uno "using" all'interno di una classe avrebbe la precedenza 
su tutti quelli esterni. Il problema continuerebbe a sussistere se se ne 
usassero più di uno, ma allora la colpa sarebbe dell'autore della classe.
Kiuhnm