Межконвертируемые типы и неоднозначные вызовы

У меня есть последовательность типов, которые я хочу свободно конвертировать друг в друга. Рассмотрим следующий игрушечный пример:

struct A {
int value;
A(int v) : value(v) { }
};

struct B {
int value;
B(int v) : value(v) { }
B(A a) : value(a.value) { }
operator A() const { return A(value); }
};

struct C {
int value;
C(int v) : value(v) { }
C(A a) : value(a.value) { }
C(B b) : value(b.value) { }
operator B() const { return B(value); }
operator A() const { return A(B(*this)); } // <-- ambiguous
};

int main(int argc, const char** argv) {
C c(5);
A a(3);
a = c;
}

Итак, как вы видите, я пытаюсь определить каждый последующий тип, который будет конвертируемым из всех предыдущих типов, используя конструкторы приведения, и конвертируемым во все предыдущие типы, используя операторы приведения. Увы, это не работает, как задумано, как определение C::operator A является неоднозначным в соответствии с GCC 4.7:

 In member function ‘C::operator A() const’:
19:40: error: call of overloaded ‘B(const C&)’ is ambiguous
19:40: note: candidates are:
9:3: note: B::B(A)
6:8: note: constexpr B::B(const B&)
6:8: note: constexpr B::B(B&&)

Изменение выражения на static_cast<A>(static_cast<B>(*this)) ничего не меняет. Удаление этой строки в целом приводит к сообщению об ошибке в main, поскольку никакая последовательность неявного преобразования не может использовать более одного определенного пользователем преобразования. В моем игрушечном примере я мог выполнить преобразование из C в A как бы то ни было, но в моем приложении из реальной жизни это приведет к появлению большого количества дублирующегося кода, поэтому я бы очень хотел найти решение, которое использует другие операторы преобразования.

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

0

Решение

Я бы попробовал этот способ в структуре C:

operator A() const { return this->operator B(); }
1

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

Попробуй это:

operator A() const { return A(B(value)); }

или это:

operator A() const { return A(operator B()); }
1

По вопросам рекламы [email protected]