Предпочитая неявное преобразование над другим - PullRequest
4 голосов
/ 15 января 2020

Я попал в ситуацию, когда у меня есть несколько пар классов, которые я назову Legacy и Modern, которые имеют конвертирующие конструкторы из тех же типов.

struct Legacy { Legacy(int); };
struct Modern { Modern(int); };

Потенциально, даже шаблонные конструкторы:

struct Legacy { template <typename T> Legacy(T); };
struct Modern { template <typename T> Modern(T); };

Аналогично, есть ряд функций, перегруженных для этих типов:

void f(Legacy) { ... }
void f(Modern) { ... }

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

f(42); // should call f(Modern(42))

[over.ics.user] не позволяет любое ранжирование в неявных преобразованиях, включающее пользовательские преобразования (другими словами, вызов неоднозначен, и все), но, возможно, я что-то упускаю.

1 Ответ

2 голосов
/ 15 января 2020

Самый простой способ сделать это - сделать конструктор Legacy явным. Это должно иметь тот же конечный эффект, что и ранжирование, потому что даже если вы «ранжировали» неявные конструкторы, единственный способ вызвать Legacy - это явно вызвать его.

Тем не менее, конвертирующие конструкторы могут быть источник путаницы и ошибок, так что вы могли бы сделать ОБА из них явными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...