В соответствии с рабочим проектом N3337 (наиболее похожим на опубликованный стандарт ISOC ++ 11), ответ не более одного
N3337:
Не более одного пользовательского преобразования (конструктор или преобразование
функция) неявно применяется к одному значению.[ Example: struct X { operator int(); }; struct Y { operator X(); }; Y a; int b = a; // error // a.operator X().operator int() not tried int c = X(a); // OK: a.operator X().operator int() —end example ]
Но по результатам компиляции main.cpp с gcc (Ubuntu 4.8.4-2ubuntu1 ~ 14.04) 4.8.4 и работает a.out с цитируемыми утверждениями в Ubuntu 14.04.3 LTS, ответ не один.
main.cpp:
#include <iostream>
struct As
{
operator int(){ std::cout<<"operator As::int()"<<std::endl; return 1; }
};
struct Bs
{
operator int(){ std::cout<<"operator Bs::int()"<<std::endl; return As(); }
};
int main()
{
int i=Bs();
return 0;
}
компилирование и запуск из терминала:
$ g++ -std=c++11 main.cpp
$ ./a.out
результат (выход):
operator Bs::int()
operator As::int()
Я что-то неправильно понял, или N3337 не так, или gcc содержит ошибку?
Здесь нет двойных преобразований.
У вас есть два отдельных обращения в двух разных местах.
Одно преобразование в B::operator int()
,
Второе преобразование в вашем main()
,
Давайте попробуем продумать это логически:
Удалите main () полностью из вашего модуля перевода. Видите ли вы двойные преобразования?
Нет.
Теперь давайте создадим заголовочный файл, содержащий следующие биты, назовите его structures.H
:
struct As
{
operator int();
};
struct Bs
{
operator int();
};
Теперь создайте structures.C
файл, содержащий содержимое каждого из этих операторов:
#include <structures.H>
B::operator int(){ std::cout<<"operator As::int()"<<std::endl; return 1; }
A::operator int(){ std::cout<<"operator Bs::int()"<<std::endl; return As(); }
Хорошо, вы все еще видите здесь двойные преобразования? Нет.
Теперь создайте свой main.C:
#include <structures.H>
int main()
{
int i=Bs();
return 0;
}
Видите ли вы здесь двойные преобразования? Нет, хотя то, что мы имеем сейчас, с двумя модулями перевода, точно такой же код, с которого вы начали.
int i=Bs();
Запускает Bs::operator int()
неявно.
return As()
Запускает As::operator int()
неявно.
Это два отдельных выражения.