Цепочка операторов неявного преобразования

У меня есть класс, который мне нужно неявно преобразовать в несколько вещей с промежуточными значениями, например.

struct outer {
    struct inner {
        operator T() { return T(); }
    };
    operator inner() { return inner(); }
};

Если у меня есть эта структура, допустимо ли это всегда, например

void f(T t);
outer o;
f(o);

person Puppy    schedule 22.12.2011    source источник
comment
Что такое T? Тип шаблона?   -  person Mooing Duck    schedule 23.12.2011
comment
@MooingDuck: тип. Неважно, что такое Т. Это не шаблон, потому что я не брал никаких параметров?   -  person Puppy    schedule 23.12.2011
comment
f(o) потребуются два определяемых пользователем преобразования, в то время как стандарт допускает максимальное стандартное преобразование -> преобразование u-d -> стандартное преобразование.   -  person Gene Bushuyev    schedule 23.12.2011
comment
Компилятор автоматически выполнит только одно неявное преобразование. Обычно неявных преобразований лучше избегать — они усложняют понимание и сопровождение кода.   -  person mark    schedule 23.12.2011


Ответы (2)


§13.3.3.1.2 [over.ics.user] p1

Определяемая пользователем последовательность преобразования состоит из исходной стандартной последовательности преобразования, за которой следует определяемое пользователем преобразование (12.3), за которой следует вторая стандартная последовательность преобразования.

Обратите внимание на единственное число и отсутствие слова «последовательность». Во время последовательности неявных преобразований будет учитываться только одно определяемое пользователем преобразование.

person Xeo    schedule 22.12.2011
comment
Есть ли соответствующий бит, указывающий, что произойдет только одна определяемая пользователем последовательность преобразования? - person ssube; 23.12.2011
comment
@peachykeen это само определение передачи параметров. Для типов классов это включает одну определяемую пользователем последовательность преобразования (если тип аргумента отличается от типа параметра), за которой следует окончательная копия временного результирующего T в параметр типа T. - person Johannes Schaub - litb; 23.12.2011

Это работает:

struct Foo {}; // renamed T in Foo to avoid confusion!

struct outer {
        struct inner {
                operator Foo() { return Foo(); }
        };

        operator inner() { return inner(); }

        template <typename T>
        operator T () {
                return operator inner();
        }
};

int main() {
        void f(Foo t);
        outer o;
        f(o);
}

Но только потому, что f не перегружен, так что это не совсем решение.

person curiousguy    schedule 23.12.2011
comment
Если бы это было приемлемо, я бы просто сделал оператор Foo во внешнем классе. - person Puppy; 23.12.2011
comment
Я не удивлен, что это неприемлемо, но это лучшее исправление, которое я получил. - person curiousguy; 24.12.2011