• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dziwne zachowanie kompilatora wobec szablonów,operatora << i przestrzeni nazw

0 głosów
120 wizyt
pytanie zadane 15 grudnia 2019 w C i C++ przez DamianW Bywalec (2,080 p.)

Witam , mam problem z dziwnym zachowaniem kompilatora podczas przeciążania operatora << w poniższej klasie:

#ifndef VECTORS_H
#define VECTORS_H
#include <iostream>
#include <vector>

namespace enbr { // <---

template<class T>
class AnyVector {
public:
     AnyVector(const std::initializer_list<T>&);// zapewniony
    ~AnyVector(); //zapewniony
private:
    unsigned int size;
    std::vector<T> element;
public:
    template<class U>
    friend std::ostream& operator<< (std::ostream&,const enbr::AnyVector<U>&);

};

} // <---

template<class U>
std::ostream& operator<< (std::ostream& os,const enbr::AnyVector<U>& vec){
    for(unsigned int i = 0;i< vec.get_size();i++)// zapewniłem funkcję get_size()
        os << vec.element[i] << " ";
    return os;
}
#endif // VECTORS_H

W tym przypadku wyskakuje błąd :

main.cpp / błąd: use of overloaded operator '<<' is ambiguous (with operand types 'std::ostream' (aka 'basic_ostream<char>') and 'enbr::AnyVector<double>')

main.cpp: błąd: ambiguous overload for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘enbr::AnyVector<double>’)
     std::cout << v1;

Ale ,gdy zasięgiem przestrzeni nazw embr obejmę również definicję operatora << , to problem znika. Dlaczego ?

#ifndef VECTORS_H
#define VECTORS_H
#include <iostream>
#include <vector>

namespace enbr { // <---

template<class T>
class AnyVector {
public:
     AnyVector(const std::initializer_list<T>&);// zapewniony
    ~AnyVector(); //zapewniony
private:
    unsigned int size;
    std::vector<T> element;
public:
    template<class U>
    friend std::ostream& operator<< (std::ostream&,const enbr::AnyVector<U>&);

};

template<class U>
std::ostream& operator<< (std::ostream& os,const enbr::AnyVector<U>& vec){
    for(unsigned int i = 0;i< vec.get_size();i++)// zapewniłem funkcję get_size()
        os << vec.element[i] << " ";
    return os;
}
} // <---
#endif // VECTORS_H

main.cpp


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

int main(){
    enbr::AnyVector<double> v1{3.0,3.0,4.0};
    std::cout << v1;
    return 0;
}

 

1 odpowiedź

+1 głos
odpowiedź 15 grudnia 2019 przez Radfler VIP (101,030 p.)
wybrane 15 grudnia 2019 przez DamianW
 
Najlepsza

W tym nie ma nic dziwnego:

namespace enbr {
template<class T>
class AnyVector {
    // ...
public:
    template<class U>
    friend std::ostream& operator<< (std::ostream&,const enbr::AnyVector<U>&); // (1)
};
 
} // namespace embr
 
template<class U>
std::ostream& operator<< (std::ostream& os,const enbr::AnyVector<U>& vec){ // (2)
    for(unsigned int i = 0;i< vec.get_size();i++)// zapewniłem funkcję get_size()
        os << vec.element[i] << " ";
    return os;
}

W wypadku kiedy definiujesz operator<< poza przestrzenią enbr tak naprawdę tworzysz kompletnie inną funkcję, tj. deklaracje (1) i (2) nie dotyczą tej samej funkcji. Z tego powodu kompilator nie wie, którą funkcję wybrać: czy (1), znalezioną dzięki ADL, czy (2) znalezioną poprzez "unqualified name lookup". W momencie kiedy umieszczasz definicję operatora w przestrzeni enbr obie deklaracje dotyczą tej samej funkcji i wszystko jest w porządku.

1
komentarz 15 grudnia 2019 przez DamianW Bywalec (2,080 p.)
Dzięki wielkie!

Podobne pytania

0 głosów
1 odpowiedź 83 wizyt
pytanie zadane 10 czerwca 2020 w C# przez Bartek12 Mądrala (5,510 p.)
0 głosów
1 odpowiedź 74 wizyt
0 głosów
4 odpowiedzi 721 wizyt
pytanie zadane 16 sierpnia 2016 w C i C++ przez Munvik Dyskutant (9,350 p.)

88,701 zapytań

137,308 odpowiedzi

306,748 komentarzy

58,894 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...