2016-02-08 2 views
1

Пробовал C++ 11 с g ++ 5.3.1 на некоторое время ... Я думал, что понял неявные операторы преобразования. Вообще говоря, , если я определяю Class3::operator Class2(), тогда я могу передать Class3 непосредственно в любую функцию, которая принимает Class2. Кажется работать 99% времени ... Но я столкнулся с простым примером, где это не тот случай.Неявное преобразование C++ не работает

class Class1 {}; 

class Class2 { 
public: 
    inline friend Class1 & operator<<(Class1 & a, Class2 const& c) 
    {return a;} 
}; 

class Class3 { 
public: 
    inline operator Class2() const {return Class2();} 
}; 

void Foo(Class2 c) {} 

int main() 
{ 
    Class1 c1; 
    Class3 c3; 

    // g++ does not like this: 
    // error: no match for 'operator<<' (operand types are 'Class1' and 'Class3') 
    // c1 << c3; 

    // g++ likes these just fine: 
    Foo(c3); 
    c1 << Class2(c3); 
} 

Любые идеи, что я сделал не так? Пожалуйста, помогите! Благодарю.

+0

Вы не определили перегрузку '' '' '' 'для класса 3, поэтому g ++ не нравится. Вы конвертируете Class3 'c3' в Class2, который является определенным вами оператором преобразования. g ++ нравится, потому что вы его определили. Будьте похожи на g ++. – Poriferous

+0

Какое сообщение об ошибке вы получаете? –

+0

@Poriferous Я не вижу, как это все объясняет. –

ответ

5

friend функция, определенная внутри определения класса, без декларации вне-класса, может видеть только аргументу зависящие от поиска, и только если класс они определены в это связанном классе одного из аргументов ,

Class2 не связанный с ним класс Class1 или Class3, и ваш operator<< не объявлен вне класса, поэтому он не будет найден по имени поиска для c1 << c3. Не зная, что такой operator<< существует, неявное преобразование просто не вступает в игру.

+0

Действительно, это, кажется, работает в небольшой тест: 'встроенный Class1 и оператор << (Class1 & а, Class2 сопзЬ & с) {возвращать;}' –

+0

ОК, получил это работает в основном код филиала Я тоже работал ... Спасибо, ваш ответ на месте. Но, теперь, кто-нибудь знает, ПОЧЕМУ у языка будет такое раздражающее ограничение? Чтобы заставить мою кодовую базу работать, мне пришлось переместить весь «оператор <<» из классов из пространств имен ... разве это не все против разумной рекомендации стиля? –

+0

Когда вы говорите _associated_, вы имеете в виду «иметь прямое наследование»? Существует некоторая двусмысленность в этом термине применительно к C++: [http://programmers.stackexchange.com/questions/255973/c-association-aggregation-and-composition] –

Смежные вопросы