Максимум, сколько пользовательских преобразований может быть неявно применено во время неявного преобразования типов?

В соответствии с рабочим проектом 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 содержит ошибку?

2

Решение

Здесь нет двойных преобразований.

У вас есть два отдельных обращения в двух разных местах.

Одно преобразование в 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;
}

Видите ли вы здесь двойные преобразования? Нет, хотя то, что мы имеем сейчас, с двумя модулями перевода, точно такой же код, с которого вы начали.

5

Другие решения

int i=Bs(); Запускает Bs::operator int() неявно.

return As() Запускает As::operator int() неявно.

Это два отдельных выражения.

2

По вопросам рекламы ammmcru@yandex.ru