• 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

Object Storage Arubacloud
0 głosów
196 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ź 170 wizyt
pytanie zadane 10 czerwca 2020 w C# przez Bartek12 Mądrala (5,510 p.)
0 głosów
1 odpowiedź 109 wizyt
0 głosów
2 odpowiedzi 286 wizyt
pytanie zadane 18 listopada 2022 w C i C++ przez Czarus Obywatel (1,310 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...